Commit 86f42bc5 authored by Christian Kuhn's avatar Christian Kuhn
Browse files

[TASK] FormEngine: The factory

Creation of container and elements instances in the FormEngine is
hard coded and hard to overwrite or adapt.
The patch extends the existing NodeFactory with resolver code to
find an appropriate class for a given requested type. All FormEngine
internal container and element requests are now routed through
NodeFactory. This allows to loosen the strict dependency between
TCA config "type" to an implementing class by moving the resolving
code into the factory. This is done for SelectElement which is now
split into multiple smaller classes - one for each display type. The
NodeFactory is covered by unit tests since the resolving code will
become more complex and fine grained in the future.
As a side effect the patch resolves a hack in the FormDataTraverser
which no longer calls internal stuff of the select element.
The NodeFactory is prepared to be extended with an API for extensions
to steer and overwrite default implementations. This will be added
with a next patch.

Change-Id: I2253a0fe3240366d0d271a3cd82119ce3dc52012
Resolves: #67006
Releases: master
Reviewed-on: http://review.typo3.org/39517

Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
parent 5569bee6
<?php
namespace TYPO3\CMS\Backend;
/*
* 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!
*/
/**
* Generic backend exception
*/
class Exception extends \Exception {
}
\ No newline at end of file
...@@ -20,7 +20,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; ...@@ -20,7 +20,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
/** /**
* Base class for container and single elements - their abstracts extend from here. * Base class for container and single elements - their abstracts extend from here.
*/ */
abstract class AbstractNode { abstract class AbstractNode implements NodeInterface {
/** /**
* A list of global options given from parent to child elements * A list of global options given from parent to child elements
......
...@@ -18,6 +18,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; ...@@ -18,6 +18,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Lang\LanguageService; use TYPO3\CMS\Lang\LanguageService;
use TYPO3\CMS\Backend\Form\FlexFormsHelper; use TYPO3\CMS\Backend\Form\FlexFormsHelper;
use TYPO3\CMS\Backend\Form\NodeFactory;
/** /**
* Entry container to a flex form element. This container is created by * Entry container to a flex form element. This container is created by
...@@ -76,9 +77,10 @@ class FlexFormContainer extends AbstractContainer { ...@@ -76,9 +77,10 @@ class FlexFormContainer extends AbstractContainer {
$options = $this->globalOptions; $options = $this->globalOptions;
$options['flexFormDataStructureArray'] = $flexFormDataStructureArray; $options['flexFormDataStructureArray'] = $flexFormDataStructureArray;
$options['flexFormRowData'] = $flexFormRowData; $options['flexFormRowData'] = $flexFormRowData;
/** @var FlexFormLanguageContainer $flexFormLanguageContainer */ $options['type'] = 'flexFormLanguageContainer';
$flexFormLanguageContainer = GeneralUtility::makeInstance(FlexFormLanguageContainer::class); /** @var NodeFactory $nodeFactory */
return $flexFormLanguageContainer->setGlobalOptions($options)->render(); $nodeFactory = $this->globalOptions['nodeFactory'];
return $nodeFactory->create($options)->render();
} }
/** /**
......
...@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Backend\Form\Container; ...@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Backend\Form\Container;
use TYPO3\CMS\Backend\Utility\IconUtility; use TYPO3\CMS\Backend\Utility\IconUtility;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Backend\Form\NodeFactory;
/** /**
* Flex form container implementation * Flex form container implementation
...@@ -94,9 +95,10 @@ class FlexFormContainerContainer extends AbstractContainer { ...@@ -94,9 +95,10 @@ class FlexFormContainerContainer extends AbstractContainer {
$options['flexFormFieldIdentifierPrefix'] = $flexFormFieldIdentifierPrefix; $options['flexFormFieldIdentifierPrefix'] = $flexFormFieldIdentifierPrefix;
// Append container specific stuff to field prefix // Append container specific stuff to field prefix
$options['flexFormFormPrefix'] = $flexFormFormPrefix . '[' . $flexFormContainerCounter . '][' . $this->globalOptions['flexFormContainerName'] . '][el]'; $options['flexFormFormPrefix'] = $flexFormFormPrefix . '[' . $flexFormContainerCounter . '][' . $this->globalOptions['flexFormContainerName'] . '][el]';
/** @var FlexFormElementContainer $containerContent */ $options['type'] = 'flexFormElementContainer';
$containerContent = GeneralUtility::makeInstance(FlexFormElementContainer::class); /** @var NodeFactory $nodeFactory */
$containerContentResult = $containerContent->setGlobalOptions($options)->render(); $nodeFactory = $this->globalOptions['nodeFactory'];
$containerContentResult = $nodeFactory->create($options)->render();
$html = array(); $html = array();
$html[] = '<div id="' . $flexFormFieldIdentifierPrefix . '" class="t3-form-field-container-flexsections t3-flex-section">'; $html[] = '<div id="' . $flexFormFieldIdentifierPrefix . '" class="t3-form-field-container-flexsections t3-flex-section">';
......
...@@ -78,9 +78,10 @@ class FlexFormElementContainer extends AbstractContainer { ...@@ -78,9 +78,10 @@ class FlexFormElementContainer extends AbstractContainer {
$options['flexFormRowData'] = is_array($flexFormRowData[$flexFormFieldName]['el']) ? $flexFormRowData[$flexFormFieldName]['el'] : array(); $options['flexFormRowData'] = is_array($flexFormRowData[$flexFormFieldName]['el']) ? $flexFormRowData[$flexFormFieldName]['el'] : array();
$options['flexFormSectionType'] = $flexFormFieldName; $options['flexFormSectionType'] = $flexFormFieldName;
$options['flexFormSectionTitle'] = $sectionTitle; $options['flexFormSectionTitle'] = $sectionTitle;
/** @var FlexFormSectionContainer $sectionContainer */ $options['type'] = 'flexFormSectionContainer';
$sectionContainer = GeneralUtility::makeInstance(FlexFormSectionContainer::class); /** @var NodeFactory $nodeFactory */
$sectionContainerResult = $sectionContainer->setGlobalOptions($options)->render(); $nodeFactory = $this->globalOptions['nodeFactory'];
$sectionContainerResult = $nodeFactory->create($options)->render();
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $sectionContainerResult); $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $sectionContainerResult);
} else { } else {
// Single element // Single element
...@@ -146,10 +147,10 @@ class FlexFormElementContainer extends AbstractContainer { ...@@ -146,10 +147,10 @@ class FlexFormElementContainer extends AbstractContainer {
$options = $this->globalOptions; $options = $this->globalOptions;
$options['parameterArray'] = $fakeParameterArray; $options['parameterArray'] = $fakeParameterArray;
$options['elementBaseName'] = $this->globalOptions['elementBaseName'] . $flexFormFormPrefix . '[' . $flexFormFieldName . '][' . $vDEFkey . ']'; $options['elementBaseName'] = $this->globalOptions['elementBaseName'] . $flexFormFormPrefix . '[' . $flexFormFieldName . '][' . $vDEFkey . ']';
$options['type'] = $flexFormFieldArray['TCEforms']['config']['type'];
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = GeneralUtility::makeInstance(NodeFactory::class); $nodeFactory = $this->globalOptions['nodeFactory'];
$child = $nodeFactory->create($flexFormFieldArray['TCEforms']['config']['type']); $childResult = $nodeFactory->create($options)->render();
$childResult = $child->setGlobalOptions($options)->render();
$theTitle = htmlspecialchars($fakeParameterArray['fieldConf']['label']); $theTitle = htmlspecialchars($fakeParameterArray['fieldConf']['label']);
$defInfo = array(); $defInfo = array();
......
...@@ -20,6 +20,7 @@ use TYPO3\CMS\Backend\Form\Utility\FormEngineUtility; ...@@ -20,6 +20,7 @@ use TYPO3\CMS\Backend\Form\Utility\FormEngineUtility;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Database\DatabaseConnection; use TYPO3\CMS\Core\Database\DatabaseConnection;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Backend\Form\NodeFactory;
/** /**
* Handle flex form language overlays. * Handle flex form language overlays.
...@@ -98,14 +99,16 @@ class FlexFormLanguageContainer extends AbstractContainer { ...@@ -98,14 +99,16 @@ class FlexFormLanguageContainer extends AbstractContainer {
$options['flexFormCurrentLanguage'] = $flexFormCurrentLanguage; $options['flexFormCurrentLanguage'] = $flexFormCurrentLanguage;
$options['flexFormNoEditDefaultLanguage'] = $flexFormNoEditDefaultLanguage; $options['flexFormNoEditDefaultLanguage'] = $flexFormNoEditDefaultLanguage;
if (!$hasTabs) { if (!$hasTabs) {
/** @var FlexFormNoTabsContainer $flexFormNoTabsContainer */ $options['type'] = 'flexFormNoTabsContainer';
$flexFormNoTabsContainer = GeneralUtility::makeInstance(FlexFormNoTabsContainer::class); /** @var NodeFactory $nodeFactory */
$flexFormNoTabsResult = $flexFormNoTabsContainer->setGlobalOptions($options)->render(); $nodeFactory = $this->globalOptions['nodeFactory'];
$flexFormNoTabsResult = $nodeFactory->create($options)->render();
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $flexFormNoTabsResult); $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $flexFormNoTabsResult);
} else { } else {
/** @var FlexFormTabsContainer $flexFormTabsContainer */ $options['type'] = 'flexFormTabsContainer';
$flexFormTabsContainer = GeneralUtility::makeInstance(FlexFormTabsContainer::class); /** @var NodeFactory $nodeFactory */
$flexFormTabsContainerResult = $flexFormTabsContainer->setGlobalOptions($options)->render(); $nodeFactory = $this->globalOptions['nodeFactory'];
$flexFormTabsContainerResult = $nodeFactory->create($options)->render();
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $flexFormTabsContainerResult); $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $flexFormTabsContainerResult);
} }
} }
......
...@@ -15,6 +15,7 @@ namespace TYPO3\CMS\Backend\Form\Container; ...@@ -15,6 +15,7 @@ namespace TYPO3\CMS\Backend\Form\Container;
*/ */
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Backend\Form\NodeFactory;
/** /**
* Handle a flex form that has no tabs. * Handle a flex form that has no tabs.
...@@ -77,9 +78,10 @@ class FlexFormNoTabsContainer extends AbstractContainer { ...@@ -77,9 +78,10 @@ class FlexFormNoTabsContainer extends AbstractContainer {
$options['flexFormFormPrefix'] = '[data][' . $flexFormSheetNameInRowData . '][' . $flexFormCurrentLanguage . ']'; $options['flexFormFormPrefix'] = '[data][' . $flexFormSheetNameInRowData . '][' . $flexFormCurrentLanguage . ']';
$options['parameterArray'] = $parameterArray; $options['parameterArray'] = $parameterArray;
/** @var FlexFormElementContainer $flexFormElementContainer */ $options['type'] = 'flexFormElementContainer';
$flexFormElementContainer = GeneralUtility::makeInstance(FlexFormElementContainer::class); /** @var NodeFactory $nodeFactory */
return $flexFormElementContainer->setGlobalOptions($options)->render(); $nodeFactory = $this->globalOptions['nodeFactory'];
return $nodeFactory->create($options)->render();
} }
} }
...@@ -18,6 +18,7 @@ use TYPO3\CMS\Backend\Utility\IconUtility; ...@@ -18,6 +18,7 @@ use TYPO3\CMS\Backend\Utility\IconUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Lang\LanguageService; use TYPO3\CMS\Lang\LanguageService;
use TYPO3\CMS\Backend\Form\NodeFactory;
/** /**
* Handle flex form sections. * Handle flex form sections.
...@@ -75,9 +76,10 @@ class FlexFormSectionContainer extends AbstractContainer { ...@@ -75,9 +76,10 @@ class FlexFormSectionContainer extends AbstractContainer {
$options['flexFormContainerCounter'] = $flexFormContainerCounter; $options['flexFormContainerCounter'] = $flexFormContainerCounter;
$options['flexFormContainerTitle'] = $sectionTitle; $options['flexFormContainerTitle'] = $sectionTitle;
$options['flexFormContainerElementCollapsed'] = (bool)$existingSectionContainerData['el']['_TOGGLE']; $options['flexFormContainerElementCollapsed'] = (bool)$existingSectionContainerData['el']['_TOGGLE'];
/** @var FlexFormContainerContainer $flexFormContainerContainer */ $options['type'] = 'flexFormContainerContainer';
$flexFormContainerContainer = GeneralUtility::makeInstance(FlexFormContainerContainer::class); /** @var NodeFactory $nodeFactory */
$flexFormContainerContainerResult = $flexFormContainerContainer->setGlobalOptions($options)->render(); $nodeFactory = $this->globalOptions['nodeFactory'];
$flexFormContainerContainerResult = $nodeFactory->create($options)->render();
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $flexFormContainerContainerResult); $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $flexFormContainerContainerResult);
} }
} }
...@@ -103,9 +105,10 @@ class FlexFormSectionContainer extends AbstractContainer { ...@@ -103,9 +105,10 @@ class FlexFormSectionContainer extends AbstractContainer {
$options['flexFormContainerCounter'] = $flexFormFieldIdentifierPrefix . '-form'; $options['flexFormContainerCounter'] = $flexFormFieldIdentifierPrefix . '-form';
$options['flexFormContainerTitle'] = $sectionTitle; $options['flexFormContainerTitle'] = $sectionTitle;
$options['flexFormContainerElementCollapsed'] = FALSE; $options['flexFormContainerElementCollapsed'] = FALSE;
/** @var FlexFormContainerContainer $flexFormContainerContainer */ $options['type'] = 'flexFormContainerContainer';
$flexFormContainerContainerTemplate = GeneralUtility::makeInstance(FlexFormContainerContainer::class); /** @var NodeFactory $nodeFactory */
$flexFormContainerContainerTemplateResult = $flexFormContainerContainerTemplate->setGlobalOptions($options)->render(); $nodeFactory = $this->globalOptions['nodeFactory'];
$flexFormContainerContainerTemplateResult = $nodeFactory->create($options)->render();
$uniqueId = str_replace('.', '', uniqid('idvar', TRUE)); $uniqueId = str_replace('.', '', uniqid('idvar', TRUE));
$identifierPrefixJs = 'replace(/' . $flexFormFieldIdentifierPrefix . '-/g,"' . $flexFormFieldIdentifierPrefix . '-"+' . $uniqueId . '+"-")'; $identifierPrefixJs = 'replace(/' . $flexFormFieldIdentifierPrefix . '-/g,"' . $flexFormFieldIdentifierPrefix . '-"+' . $uniqueId . '+"-")';
......
...@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Backend\Form\Container; ...@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Backend\Form\Container;
use TYPO3\CMS\Backend\Template\DocumentTemplate; use TYPO3\CMS\Backend\Template\DocumentTemplate;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Lang\LanguageService; use TYPO3\CMS\Lang\LanguageService;
use TYPO3\CMS\Backend\Form\NodeFactory;
/** /**
* Handle flex forms that have tabs (multiple "sheets"). * Handle flex forms that have tabs (multiple "sheets").
...@@ -91,9 +92,10 @@ class FlexFormTabsContainer extends AbstractContainer { ...@@ -91,9 +92,10 @@ class FlexFormTabsContainer extends AbstractContainer {
'tab', 'tab',
$tabIdString . '-' . $tabCounter, $tabIdString . '-' . $tabCounter,
); );
/** @var FlexFormElementContainer $flexFormElementContainer */ $options['type'] = 'flexFormElementContainer';
$flexFormElementContainer = GeneralUtility::makeInstance(FlexFormElementContainer::class); /** @var NodeFactory $nodeFactory */
$childReturn = $flexFormElementContainer->setGlobalOptions($options)->render(); $nodeFactory = $this->globalOptions['nodeFactory'];
$childReturn = $nodeFactory->create($options)->render();
$tabsContent[] = array( $tabsContent[] = array(
'label' => !empty($sheetDataStructure['ROOT']['TCEforms']['sheetTitle']) ? $languageService->sL($sheetDataStructure['ROOT']['TCEforms']['sheetTitle']) : $sheetName, 'label' => !empty($sheetDataStructure['ROOT']['TCEforms']['sheetTitle']) ? $languageService->sL($sheetDataStructure['ROOT']['TCEforms']['sheetTitle']) : $sheetName,
......
...@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Backend\Form\Container; ...@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Backend\Form\Container;
use TYPO3\CMS\Lang\LanguageService; use TYPO3\CMS\Lang\LanguageService;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Backend\Form\NodeFactory;
/** /**
* A container rendering a "full record". This is an entry container used as first * A container rendering a "full record". This is an entry container used as first
...@@ -103,15 +104,15 @@ class FullRecordContainer extends AbstractContainer { ...@@ -103,15 +104,15 @@ class FullRecordContainer extends AbstractContainer {
$options['additionalPreviewLanguageData'] = $this->additionalPreviewLanguageData; $options['additionalPreviewLanguageData'] = $this->additionalPreviewLanguageData;
if ($hasTabs) { if ($hasTabs) {
/** @var TabsContainer $TabsContainer */ $options['type'] = 'tabsContainer';
$container = GeneralUtility::makeInstance(TabsContainer::class); /** @var NodeFactory $nodeFactory */
$container->setGlobalOptions($options); $nodeFactory = $this->globalOptions['nodeFactory'];
$resultArray = $container->render(); $resultArray = $nodeFactory->create($options)->render();
} else { } else {
/** @var NoTabsContainer $NoTabsContainer */ $options['type'] = 'noTabsContainer';
$container = GeneralUtility::makeInstance(NoTabsContainer::class); /** @var NodeFactory $nodeFactory */
$container->setGlobalOptions($options); $nodeFactory = $this->globalOptions['nodeFactory'];
$resultArray = $container->render(); $resultArray = $nodeFactory->create($options)->render();
} }
return $resultArray; return $resultArray;
......
...@@ -26,6 +26,7 @@ use TYPO3\CMS\Backend\Form\Utility\FormEngineUtility; ...@@ -26,6 +26,7 @@ use TYPO3\CMS\Backend\Form\Utility\FormEngineUtility;
use TYPO3\CMS\Backend\Utility\IconUtility; use TYPO3\CMS\Backend\Utility\IconUtility;
use TYPO3\CMS\Backend\Form\InlineStackProcessor; use TYPO3\CMS\Backend\Form\InlineStackProcessor;
use TYPO3\CMS\Backend\Form\InlineRelatedRecordResolver; use TYPO3\CMS\Backend\Form\InlineRelatedRecordResolver;
use TYPO3\CMS\Backend\Form\NodeFactory;
/** /**
* Inline element entry container. * Inline element entry container.
...@@ -222,9 +223,10 @@ class InlineControlContainer extends AbstractContainer { ...@@ -222,9 +223,10 @@ class InlineControlContainer extends AbstractContainer {
$options['inlineRelatedRecordConfig'] = $config; $options['inlineRelatedRecordConfig'] = $config;
$options['inlineData'] = $this->inlineData; $options['inlineData'] = $this->inlineData;
$options['inlineStructure'] = $inlineStackProcessor->getStructure(); $options['inlineStructure'] = $inlineStackProcessor->getStructure();
/** @var InlineRecordContainer $inlineRecordContainer */ $options['type'] = 'inlineRecordContainer';
$inlineRecordContainer = GeneralUtility::makeInstance(InlineRecordContainer::class); /** @var NodeFactory $nodeFactory */
$childArray = $inlineRecordContainer->setGlobalOptions($options)->render(); $nodeFactory = $this->globalOptions['nodeFactory'];
$childArray = $nodeFactory->create($options)->render();
$html .= $childArray['html']; $html .= $childArray['html'];
$childArray['html'] = ''; $childArray['html'] = '';
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $childArray); $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $childArray);
...@@ -654,4 +656,4 @@ class InlineControlContainer extends AbstractContainer { ...@@ -654,4 +656,4 @@ class InlineControlContainer extends AbstractContainer {
return $GLOBALS['LANG']; return $GLOBALS['LANG'];
} }
} }
\ No newline at end of file
...@@ -30,6 +30,7 @@ use TYPO3\CMS\Core\Database\RelationHandler; ...@@ -30,6 +30,7 @@ use TYPO3\CMS\Core\Database\RelationHandler;
use TYPO3\CMS\Core\Database\DatabaseConnection; use TYPO3\CMS\Core\Database\DatabaseConnection;
use TYPO3\CMS\Backend\Form\InlineStackProcessor; use TYPO3\CMS\Backend\Form\InlineStackProcessor;
use TYPO3\CMS\Backend\Form\InlineRelatedRecordResolver; use TYPO3\CMS\Backend\Form\InlineRelatedRecordResolver;
use TYPO3\CMS\Backend\Form\NodeFactory;
/** /**
* Render a single inline record relation. * Render a single inline record relation.
...@@ -216,9 +217,10 @@ class InlineRecordContainer extends AbstractContainer { ...@@ -216,9 +217,10 @@ class InlineRecordContainer extends AbstractContainer {
$domObjectId . '-' . $table . '-' . $row['uid'], $domObjectId . '-' . $table . '-' . $row['uid'],
); );
$options['overruleTypesArray'] = $overruleTypesArray; $options['overruleTypesArray'] = $overruleTypesArray;
/** @var FullRecordContainer $entryContainer */ $options['type'] = 'fullRecordContainer';
$entryContainer = GeneralUtility::makeInstance(FullRecordContainer::class); /** @var NodeFactory $nodeFactory */
return $entryContainer->setGlobalOptions($options)->render(); $nodeFactory = $this->globalOptions['nodeFactory'];
return $nodeFactory->create($options)->render();
} }
/** /**
......
...@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Backend\Form\Container; ...@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Backend\Form\Container;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Lang\LanguageService; use TYPO3\CMS\Lang\LanguageService;
use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Backend\Form\NodeFactory;
/** /**
* Render a given list of field of a TCA table. * Render a given list of field of a TCA table.
...@@ -71,10 +72,10 @@ class ListOfFieldsContainer extends AbstractContainer { ...@@ -71,10 +72,10 @@ class ListOfFieldsContainer extends AbstractContainer {
$options = $this->globalOptions; $options = $this->globalOptions;
$options['fieldsArray'] = $finalFieldsConfiguration; $options['fieldsArray'] = $finalFieldsConfiguration;
/** @var PaletteAndSingleContainer $paletteAndSingleContainer */ $options['type'] = 'paletteAndSingleContainer';
$paletteAndSingleContainer = GeneralUtility::makeInstance(PaletteAndSingleContainer::class); /** @var NodeFactory $nodeFactory */
$paletteAndSingleContainer->setGlobalOptions($options); $nodeFactory = $this->globalOptions['nodeFactory'];
return $paletteAndSingleContainer->render(); return $nodeFactory->create($options)->render();
} }
/** /**
......
...@@ -15,6 +15,7 @@ namespace TYPO3\CMS\Backend\Form\Container; ...@@ -15,6 +15,7 @@ namespace TYPO3\CMS\Backend\Form\Container;
*/ */
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Backend\Form\NodeFactory;
/** /**
* Handle a record that has no tabs. * Handle a record that has no tabs.
...@@ -30,10 +31,11 @@ class NoTabsContainer extends AbstractContainer { ...@@ -30,10 +31,11 @@ class NoTabsContainer extends AbstractContainer {
* @return array As defined in initializeResultArray() of AbstractNode * @return array As defined in initializeResultArray() of AbstractNode
*/ */
public function render() { public function render() {
/** @var PaletteAndSingleContainer $paletteAndSingleContainer */ $options = $this->globalOptions;
$paletteAndSingleContainer = GeneralUtility::makeInstance(PaletteAndSingleContainer::class); $options['type'] = 'paletteAndSingleContainer';
$paletteAndSingleContainer->setGlobalOptions($this->globalOptions); /** @var NodeFactory $nodeFactory */
$resultArray = $paletteAndSingleContainer->render(); $nodeFactory = $this->globalOptions['nodeFactory'];
$resultArray = $nodeFactory->create($options)->render();
$resultArray['html'] = '<div class="tab-content">' . $resultArray['html'] . '</div>'; $resultArray['html'] = '<div class="tab-content">' . $resultArray['html'] . '</div>';
return $resultArray; return $resultArray;
} }
......
...@@ -19,6 +19,7 @@ use TYPO3\CMS\Lang\LanguageService; ...@@ -19,6 +19,7 @@ use TYPO3\CMS\Lang\LanguageService;
use TYPO3\CMS\Backend\Utility\IconUtility; use TYPO3\CMS\Backend\Utility\IconUtility;
use TYPO3\CMS\Backend\Form\Utility\FormEngineUtility; use TYPO3\CMS\Backend\Form\Utility\FormEngineUtility;
use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Backend\Form\NodeFactory;
/** /**
* Handle palettes and single fields. * Handle palettes and single fields.
...@@ -136,10 +137,10 @@ class PaletteAndSingleContainer extends AbstractContainer { ...@@ -136,10 +137,10 @@ class PaletteAndSingleContainer extends AbstractContainer {
$options['fieldName'] = $fieldName; $options['fieldName'] = $fieldName;
$options['fieldExtra'] = $fieldConfiguration['fieldExtra']; $options['fieldExtra'] = $fieldConfiguration['fieldExtra'];
/** @var SingleFieldContainer $singleFieldContainer */ $options['type'] = 'singleFieldContainer';
$singleFieldContainer = GeneralUtility::makeInstance(SingleFieldContainer::class); /** @var NodeFactory $nodeFactory */
$singleFieldContainer->setGlobalOptions($options); $nodeFactory = $this->globalOptions['nodeFactory'];
$childResultArray = $singleFieldContainer->render(); $childResultArray = $nodeFactory->create($options)->render();
if (!empty($childResultArray['html'])) { if (!empty($childResultArray['html'])) {
$mainStructureCounter ++; $mainStructureCounter ++;
...@@ -260,10 +261,10 @@ class PaletteAndSingleContainer extends AbstractContainer { ...@@ -260,10 +261,10 @@ class PaletteAndSingleContainer extends AbstractContainer {
$options['fieldName'] = $fieldName; $options['fieldName'] = $fieldName;
$options['fieldExtra'] = $fieldArray['fieldExtra']; $options['fieldExtra'] = $fieldArray['fieldExtra'];
/** @var SingleFieldContainer $singleFieldContainer */ $options['type'] = 'singleFieldContainer';
$singleFieldContainer = GeneralUtility::makeInstance(SingleFieldContainer::class); /** @var NodeFactory $nodeFactory */
$singleFieldContainer->setGlobalOptions($options); $nodeFactory = $this->globalOptions['nodeFactory'];
$singleFieldContentArray = $singleFieldContainer->render(); $singleFieldContentArray = $nodeFactory->create($options)->render();
if (!empty($singleFieldContentArray['html'])) { if (!empty($singleFieldContentArray['html'])) {
$foundRealElement = TRUE; $foundRealElement = TRUE;
......
...@@ -25,7 +25,6 @@ use TYPO3\CMS\Backend\Utility\IconUtility; ...@@ -25,7 +25,6 @@ use TYPO3\CMS\Backend\Utility\IconUtility;
use TYPO3\CMS\Core\Utility\DiffUtility; use TYPO3\CMS\Core\Utility\DiffUtility;
use TYPO3\CMS\Backend\Form\InlineStackProcessor; use TYPO3\CMS\Backend\Form\InlineStackProcessor;
use TYPO3\CMS\Core\Database\RelationHandler; use TYPO3\CMS\Core\Database\RelationHandler;
use TYPO3\CMS\Backend\Form\Element\NoneElement;
/** /**
* Container around a "single field". * Container around a "single field".
...@@ -160,10 +159,10 @@ class SingleFieldContainer extends AbstractContainer { ...@@ -160,10 +159,10 @@ class SingleFieldContainer extends AbstractContainer {
$options = $this->globalOptions; $options = $this->globalOptions;
$options['parameterArray'] = $parameterArray; $options['parameterArray'] = $parameterArray;
$options['elementBaseName'] = $newElementBaseName; $options['elementBaseName'] = $newElementBaseName;
/** @var NodeFactory $childFactory */ $options['type'] = $parameterArray['fieldConf']['config']['type'];
$childFactory = GeneralUtility::makeInstance(NodeFactory::class); /** @var NodeFactory $nodeFactory */
$childElement = $childFactory->create($parameterArray['fieldConf']['config']['type']); $nodeFactory = $this->globalOptions['nodeFactory'];
$resultArray = $childElement->setGlobalOptions($options)->render(); $resultArray = $nodeFactory->create($options)->render();
$html = $resultArray['html']; $html = $resultArray['html'];
// @todo: the language handling, the null and the placeholder stuff should be embedded in the single // @todo: the language handling, the null and the placeholder stuff should be embedded in the single
...@@ -253,9 +252,10 @@ class SingleFieldContainer extends AbstractContainer { ...@@ -253,9 +252,10 @@ class SingleFieldContainer extends AbstractContainer {
$options['table'] = ''; $options['table'] = '';
$options['parameterArray'] = $parameterArray; $options['parameterArray'] = $parameterArray;
$options['parameterArray']['itemFormElValue'] = GeneralUtility::fixed_lgd_cs($placeholder, 30); $options['parameterArray']['itemFormElValue'] = GeneralUtility::fixed_lgd_cs($placeholder, 30);