TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace TYPO3\CMS\Backend\Form\Container;
|
||||
|
||||
use TYPO3\CMS\Backend\Form\Behavior\ReloadOnFieldChange;
|
||||
use TYPO3\CMS\Backend\Form\Behavior\UpdateValueOnFieldChange;
|
||||
use TYPO3\CMS\Core\Authentication\JsConfirmation;
|
||||
use TYPO3\CMS\Core\Localization\LanguageService;
|
||||
|
||||
/**
|
||||
* The container handles single elements.
|
||||
*
|
||||
* This one is called by FlexFormTabsContainer, FlexFormNoTabsContainer or FlexFormContainerContainer.
|
||||
* For single fields, the code is similar to SingleFieldContainer, processing will end up in single
|
||||
* element classes depending on specific renderType of an element. Additionally, it determines if a
|
||||
* section is handled and hands over to FlexFormSectionContainer in this case.
|
||||
*/
|
||||
class FlexFormElementContainer extends AbstractContainer
|
||||
{
|
||||
/**
|
||||
* Entry method
|
||||
*
|
||||
* @return array As defined in initializeResultArray() of AbstractNode
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$flexFormDataStructureArray = $this->data['flexFormDataStructureArray'];
|
||||
$flexFormRowData = $this->data['flexFormRowData'];
|
||||
$flexFormFormPrefix = $this->data['flexFormFormPrefix'];
|
||||
$parameterArray = $this->data['parameterArray'];
|
||||
|
||||
$languageService = $this->getLanguageService();
|
||||
$resultArray = $this->initializeResultArray();
|
||||
|
||||
foreach ($flexFormDataStructureArray as $flexFormFieldName => $flexFormFieldArray) {
|
||||
if (
|
||||
// No item array found at all
|
||||
!is_array($flexFormFieldArray)
|
||||
// Not a section or container and not a list of single items
|
||||
|| (!isset($flexFormFieldArray['type']) && !is_array($flexFormFieldArray['config']))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (($flexFormFieldArray['type'] ?? null) === 'array') {
|
||||
// Section
|
||||
if (empty($flexFormFieldArray['section'])) {
|
||||
$resultArray['html'] = LF . 'Section expected at ' . $flexFormFieldName . ' but not found';
|
||||
continue;
|
||||
}
|
||||
|
||||
$options = $this->data;
|
||||
$options['flexFormDataStructureArray'] = $flexFormFieldArray;
|
||||
$options['flexFormRowData'] = $flexFormRowData[$flexFormFieldName]['el'] ?? [];
|
||||
$options['flexFormFieldName'] = $flexFormFieldName;
|
||||
$options['renderType'] = 'flexFormSectionContainer';
|
||||
$sectionContainerResult = $this->nodeFactory->create($options)->render();
|
||||
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $sectionContainerResult);
|
||||
} else {
|
||||
// Set up options for single element
|
||||
$fakeParameterArray = [
|
||||
'fieldConf' => [
|
||||
'label' => $languageService->sL(trim($flexFormFieldArray['label'] ?? '')),
|
||||
'config' => $flexFormFieldArray['config'] ?? [],
|
||||
'children' => $flexFormFieldArray['children'] ?? [],
|
||||
// https://docs.typo3.org/m/typo3/reference-tca/main/en-us/Columns/Properties/OnChange.html
|
||||
'onChange' => $flexFormFieldArray['onChange'] ?? '',
|
||||
],
|
||||
'fieldChangeFunc' => $parameterArray['fieldChangeFunc'],
|
||||
'label' => $parameterArray['label'] ?? '',
|
||||
];
|
||||
|
||||
if (isset($flexFormFieldArray['description']) && !empty($flexFormFieldArray['description'])) {
|
||||
$fakeParameterArray['fieldConf']['description'] = $flexFormFieldArray['description'];
|
||||
}
|
||||
|
||||
if ($fakeParameterArray['fieldConf']['onChange'] === 'reload') {
|
||||
$confirmation = $this->getBackendUserAuthentication()->jsConfirmation(JsConfirmation::TYPE_CHANGE);
|
||||
$fakeParameterArray['fieldChangeFunc']['alert'] = new ReloadOnFieldChange($confirmation);
|
||||
}
|
||||
|
||||
$originalFieldName = $parameterArray['itemFormElName'];
|
||||
$fakeParameterArray['itemFormElName'] = $parameterArray['itemFormElName'] . $flexFormFormPrefix . '[' . $flexFormFieldName . '][vDEF]';
|
||||
if ($fakeParameterArray['itemFormElName'] !== $originalFieldName) {
|
||||
// If calculated itemFormElName is different from originalFieldName
|
||||
// change the originalFieldName in TBE_EDITOR_fieldChanged. This is
|
||||
// especially relevant for wizards writing their content back to hidden fields
|
||||
$onFieldChange = $fakeParameterArray['fieldChangeFunc']['TBE_EDITOR_fieldChanged'] ?? null;
|
||||
if ($onFieldChange instanceof UpdateValueOnFieldChange) {
|
||||
$fakeParameterArray['fieldChangeFunc']['TBE_EDITOR_fieldChanged'] = $onFieldChange->withElementName($fakeParameterArray['itemFormElName']);
|
||||
}
|
||||
}
|
||||
if (array_key_exists('vDEF', $flexFormRowData[$flexFormFieldName] ?? [])) {
|
||||
$fakeParameterArray['itemFormElValue'] = $flexFormRowData[$flexFormFieldName]['vDEF'];
|
||||
} else {
|
||||
$fakeParameterArray['itemFormElValue'] = $fakeParameterArray['fieldConf']['config']['default'] ?? '';
|
||||
}
|
||||
|
||||
$options = $this->data;
|
||||
// Set either flexFormFieldName or flexFormContainerFieldName, depending on if we are a "regular" field or a flex container section field
|
||||
if (empty($options['flexFormFieldName'])) {
|
||||
$options['flexFormFieldName'] = $flexFormFieldName;
|
||||
} else {
|
||||
$options['flexFormContainerFieldName'] = $flexFormFieldName;
|
||||
}
|
||||
$options['parameterArray'] = $fakeParameterArray;
|
||||
$options['elementBaseName'] = $this->data['elementBaseName'] . $flexFormFormPrefix . '[' . $flexFormFieldName . '][vDEF]';
|
||||
|
||||
if (!empty($flexFormFieldArray['config']['renderType'])) {
|
||||
$options['renderType'] = $flexFormFieldArray['config']['renderType'];
|
||||
} else {
|
||||
// Fallback to type if no renderType is given
|
||||
$options['renderType'] = $flexFormFieldArray['config']['type'];
|
||||
}
|
||||
$childResult = $this->nodeFactory->create($options)->render();
|
||||
|
||||
if (!empty($childResult['html'])) {
|
||||
$html = [];
|
||||
$html[] = '<div class="form-section" data-id="' . htmlspecialchars($flexFormFieldName) . '">';
|
||||
$html[] = '<div class="form-group t3js-formengine-palette-field t3js-formengine-validation-marker">';
|
||||
$html[] = '<div class="formengine-field-item t3js-formengine-field-item">';
|
||||
$html[] = $childResult['html'];
|
||||
$html[] = '</div>';
|
||||
$html[] = '</div>';
|
||||
$html[] = '</div>';
|
||||
$resultArray['html'] .= implode(LF, $html);
|
||||
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $childResult, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $resultArray;
|
||||
}
|
||||
|
||||
protected function getLanguageService(): LanguageService
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user