getLanguageService(); /* * The first code block creates a target structure array to later create the final * HTML string. The single fields and sub containers are rendered here already and * other parts of the return array from children except html are accumulated in * $this->resultArray * $targetStructure = [ 0 => [ 'type' => 'palette', 'fieldName' => 'palette1', 'paletteLegend' => 'palette1', 'paletteDescription' => 'palette1Description', 'elements' => [ 0 => [ 'type' => 'single', 'fieldName' => 'paletteName', 'fieldHtml' => 'element1', ), 1 => [ 'type' => 'linebreak', ), 2 => [ 'type' => 'single', 'fieldName' => 'paletteName', 'fieldHtml' => 'element2', ], ], ], 1 => [ 'type' => 'single', 'fieldName' => 'element3', 'fieldHtml' => 'element3', ], 2 => [ 'type' => 'palette', 'fieldName' => 'palette2', 'paletteLegend' => '', // Palette label is optional 'paletteDescription' => '', // Palette description is optional 'elements' => [ 0 => [ 'type' => 'single', 'fieldName' => 'element4', 'fieldHtml' => 'element4', ], 1 => [ 'type' => 'linebreak', ], 2 => [ 'type' => 'single', 'fieldName' => 'element5', 'fieldHtml' => 'element5', ], ], ], ); */ // Create an intermediate structure of rendered sub elements and elements nested in palettes $targetStructure = []; $mainStructureCounter = -1; $fieldsArray = $this->data['fieldsArray']; $this->resultArray = $this->initializeResultArray(); foreach ($fieldsArray as $fieldString) { $fieldConfiguration = $this->explodeSingleFieldShowItemConfiguration($fieldString); $fieldName = $fieldConfiguration['fieldName']; if ($fieldName === '--palette--') { $paletteElementArray = $this->createPaletteContentArray($fieldConfiguration['paletteName'] ?? ''); if (!empty($paletteElementArray)) { $mainStructureCounter++; // If there is no label in ['types']['aType']['showitem'] for this palette: "--palette--;;aPalette", // then use ['palettes']['aPalette']['label'] if given. $paletteLegend = $fieldConfiguration['fieldLabel']; if ($paletteLegend === null && !empty($this->data['processedTca']['palettes'][$fieldConfiguration['paletteName']]['label'])) { $paletteLegend = $this->data['processedTca']['palettes'][$fieldConfiguration['paletteName']]['label']; } // Get description of palette. $paletteDescription = $this->data['processedTca']['palettes'][$fieldConfiguration['paletteName']]['description'] ?? ''; $targetStructure[$mainStructureCounter] = [ 'type' => 'palette', 'fieldName' => $fieldConfiguration['paletteName'], 'paletteLegend' => $languageService->sL($paletteLegend), 'paletteDescription' => $languageService->sL($paletteDescription), 'elements' => $paletteElementArray, ]; } } else { if (!is_array($this->data['processedTca']['columns'][$fieldName] ?? null)) { continue; } $options = $this->data; $options['fieldName'] = $fieldName; $options['renderType'] = 'singleFieldContainer'; $childResultArray = $this->nodeFactory->create($options)->render(); if (!empty($childResultArray['html'])) { $mainStructureCounter++; $targetStructure[$mainStructureCounter] = [ 'type' => 'single', 'fieldName' => $fieldConfiguration['fieldName'], 'fieldHtml' => $childResultArray['html'], ]; } $this->resultArray = $this->mergeChildReturnIntoExistingResult($this->resultArray, $childResultArray, false); } } // Compile final content $content = []; foreach ($targetStructure as $element) { if ($element['type'] === 'palette') { $paletteName = $element['fieldName']; $isHiddenPalette = !empty($this->data['processedTca']['palettes'][$paletteName]['isHiddenPalette']); $html = []; $html[] = '
'; if (!empty($element['paletteLegend'])) { $html[] = '

' . htmlspecialchars($element['paletteLegend']) . '

'; } if (!empty($element['paletteDescription'])) { $html[] = '

' . nl2br(htmlspecialchars($element['paletteDescription'])) . '

'; } $html[] = $this->renderInnerPaletteContent($element); $html[] = '
'; $content[] = implode(LF, $html); } else { $html = []; $html[] = '
'; $html[] = '
'; $html[] = $element['fieldHtml']; $html[] = '
'; $html[] = '
'; $content[] = implode(LF, $html); } } $finalResultArray = $this->resultArray; $finalResultArray['html'] = implode(LF, $content); return $finalResultArray; } /** * Render single fields of a given palette * * @param string $paletteName The palette to render */ protected function createPaletteContentArray(string $paletteName): array { // palette needs a palette name reference, otherwise it does not make sense to try rendering of it if (empty($paletteName) || empty($this->data['processedTca']['palettes'][$paletteName]['showitem'])) { return []; } $resultStructure = []; $foundRealElement = false; // Set to true if not only line breaks were rendered $fieldsArray = GeneralUtility::trimExplode(',', $this->data['processedTca']['palettes'][$paletteName]['showitem'], true); foreach ($fieldsArray as $fieldString) { $fieldArray = $this->explodeSingleFieldShowItemConfiguration($fieldString); $fieldName = $fieldArray['fieldName']; if ($fieldName === '--linebreak--') { $resultStructure[] = [ 'type' => 'linebreak', ]; } else { if (!is_array($this->data['processedTca']['columns'][$fieldName] ?? null)) { continue; } $options = $this->data; $options['fieldName'] = $fieldName; $options['renderType'] = 'singleFieldContainer'; $singleFieldContentArray = $this->nodeFactory->create($options)->render(); if (!empty($singleFieldContentArray['html'])) { $foundRealElement = true; $resultStructure[] = [ 'type' => 'single', 'fieldName' => $fieldName, 'fieldHtml' => $singleFieldContentArray['html'], ]; } $this->resultArray = $this->mergeChildReturnIntoExistingResult($this->resultArray, $singleFieldContentArray, false); } } if ($foundRealElement) { return $resultStructure; } return []; } /** * Renders inner content of single elements of a palette and wrap it as needed * * @param array $elementArray Array of elements * @return string Wrapped content */ protected function renderInnerPaletteContent(array $elementArray): string { $result = []; $currentGroup = []; foreach ($elementArray['elements'] as $element) { if ($element['type'] === 'linebreak') { // Render current group before linebreak if (!empty($currentGroup)) { $result[] = $this->renderFieldGroup($currentGroup); $currentGroup = []; } } else { $currentGroup[] = $element; } } // Render remaining group if (!empty($currentGroup)) { $result[] = $this->renderFieldGroup($currentGroup); } return implode(LF, $result); } /** * Renders a group of fields within a form-grid container * * @param array $fields Array of field elements * @return string Rendered HTML */ protected function renderFieldGroup(array $fields): string { $numberOfItems = count($fields); $result = []; if ($numberOfItems > 1) { $result[] = '
'; } foreach ($fields as $element) { $result[] = '
'; $result[] = $element['fieldHtml']; $result[] = '
'; } if ($numberOfItems > 1) { $result[] = '
'; } return implode(LF, $result); } protected function getLanguageService(): LanguageService { return $GLOBALS['LANG']; } }