Commit 0ee65b8f authored by Christian Kuhn's avatar Christian Kuhn Committed by Anja Leichsenring
Browse files

[!!!][FEATURE] FormEngine: The extendables

For details, see the ReST files with examples for new API
and TCA changes.

* Split TCA config "type" to "type" and "renderType":
  TCA config "type" is a technical debt since it both defines the
  database storage as well as the widget that is used to render
  a certain field in FormEngine. While "type" is kept, the
  render widget is now extracted to a "renderType".

* t3editor uses this "renderType" now. type=text with
  renderType=t3editor will call the new T3editorElement provided
  by ext:t3editor, and falls back to TextElement if t3editor is
  not loaded.

* t3editor is now enabled for "setup" and "constants" of
  sys_template records if opening the whole record.

* t3editor now works when configured in a flex form.

* Introduce an API in FormEngine NodeFactory to register new
  renderType, used by t3editor.

* Introduce a resolver API in FormEngine NodeFactory to change
  the class that renders a widget or container.

* Split TextElement into TextElement that only renders a textarea
  and RichTextElement provided by ext:rtehtmlarea that renders RTE.
  ext:rtehtmlarea uses the new resolver API to route rendering to
  its own class in case RTE is enabled and configured for a field.

* In TCA section "types" a new array "columnsOverrides" is
  introduced that allows overwriting some column configurations
  of fields. Currently, this works for some View/FormEngine related
  settings like renderType and defaultExtras.

* TCA Migration is introduced to dynamically rewrite TCA before
  it is put into cache.

* TCA migration is called a second time in ext:compatibility6 in
  case TCA is still registered via ext_tables.php. This has performance
  penalty since it is done on every frontend and backend call.

* TCA migration is also called dynamically for flex form definitions.

* TCA migration moves configured t3editor wizards to type=text with
  renderType=t3editor.

* TCA migration removes the 5th parameter "style pointer" from
  types showitem

* TCA migration moves the 4th showitem parameter "extra configuration"
  to "defaultExtras" of "columnsOverrides" of given TCA type.

Change-Id: Ia2c2bc16463a01021c7a6be765b4efa872a130fd
Resolves: #67229
Releases: master
Reviewed-on: http://review.typo3.org/39662


Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: default avatarFrank Nägler <typo3@naegler.net>
Tested-by: default avatarFrank Nägler <typo3@naegler.net>
Reviewed-by: Markus Klein's avatarMarkus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein's avatarMarkus Klein <markus.klein@typo3.org>
Reviewed-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
parent 7231ac0f
...@@ -206,20 +206,13 @@ abstract class AbstractContainer extends AbstractNode { ...@@ -206,20 +206,13 @@ abstract class AbstractContainer extends AbstractNode {
*/ */
protected function explodeSingleFieldShowItemConfiguration($field) { protected function explodeSingleFieldShowItemConfiguration($field) {
$fieldArray = GeneralUtility::trimExplode(';', $field); $fieldArray = GeneralUtility::trimExplode(';', $field);
/**
* @todo: In general, fieldName must always be given, that is why this exception would be useful.
* @todo: But in older versions there was a fifth parameter and settings like ';;;;2-2-2' were used,
* @todo; which is obsolete now. Stuff like that could later be parsed-out on a different level of the
* @todo: system, the exception could then be commented in again.
if (empty($fieldArray[0])) { if (empty($fieldArray[0])) {
throw new \RuntimeException('Field must not be empty', 1426448465); throw new \RuntimeException('Field must not be empty', 1426448465);
} }
*/
return array( return array(
'fieldName' => $fieldArray[0] ?: '', // This ternary could be removed if above todo is resolved 'fieldName' => $fieldArray[0],
'fieldLabel' => $fieldArray[1] ?: NULL, 'fieldLabel' => $fieldArray[1] ?: NULL,
'paletteName' => $fieldArray[2] ?: NULL, 'paletteName' => $fieldArray[2] ?: NULL,
'fieldExtra' => $fieldArray[3] ?: NULL,
); );
} }
......
...@@ -77,7 +77,7 @@ class FlexFormContainer extends AbstractContainer { ...@@ -77,7 +77,7 @@ class FlexFormContainer extends AbstractContainer {
$options = $this->globalOptions; $options = $this->globalOptions;
$options['flexFormDataStructureArray'] = $flexFormDataStructureArray; $options['flexFormDataStructureArray'] = $flexFormDataStructureArray;
$options['flexFormRowData'] = $flexFormRowData; $options['flexFormRowData'] = $flexFormRowData;
$options['type'] = 'flexFormLanguageContainer'; $options['renderType'] = 'flexFormLanguageContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
return $nodeFactory->create($options)->render(); return $nodeFactory->create($options)->render();
......
...@@ -95,7 +95,7 @@ class FlexFormContainerContainer extends AbstractContainer { ...@@ -95,7 +95,7 @@ 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]';
$options['type'] = 'flexFormElementContainer'; $options['renderType'] = 'flexFormElementContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$containerContentResult = $nodeFactory->create($options)->render(); $containerContentResult = $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\Backend\Form\ElementConditionMatcher; use TYPO3\CMS\Backend\Form\ElementConditionMatcher;
use TYPO3\CMS\Core\Migrations\TcaMigration;
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\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
...@@ -78,7 +79,7 @@ class FlexFormElementContainer extends AbstractContainer { ...@@ -78,7 +79,7 @@ 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;
$options['type'] = 'flexFormSectionContainer'; $options['renderType'] = 'flexFormSectionContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$sectionContainerResult = $nodeFactory->create($options)->render(); $sectionContainerResult = $nodeFactory->create($options)->render();
...@@ -99,6 +100,26 @@ class FlexFormElementContainer extends AbstractContainer { ...@@ -99,6 +100,26 @@ class FlexFormElementContainer extends AbstractContainer {
continue; continue;
} }
// On-the-fly migration for flex form "TCA"
// @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8. This can be removed *if* no additional TCA migration is added with CMS 8, see class TcaMigration
$dummyTca = array(
'dummyTable' => array(
'columns' => array(
'dummyField' => $flexFormFieldArray['TCEforms'],
),
),
);
$tcaMigration = GeneralUtility::makeInstance(TcaMigration::class);
$migratedTca = $tcaMigration->migrate($dummyTca);
$messages = $tcaMigration->getMessages();
if (!empty($messages)) {
$context = 'FormEngine did an on-the-fly migration of a flex form data structure. This is deprecated and will be removed'
. ' with TYPO3 CMS 8. Merge the following changes into the flex form definition of table ' . $table . ' in field ' . $fieldName . ':';
array_unshift($messages, $context);
GeneralUtility::deprecationLog(implode(LF, $messages));
}
$flexFormFieldArray['TCEforms'] = $migratedTca['dummyTable']['columns']['dummyField'];
// Set up options for single element // Set up options for single element
$fakeParameterArray = array( $fakeParameterArray = array(
'fieldConf' => array( 'fieldConf' => array(
...@@ -147,7 +168,13 @@ class FlexFormElementContainer extends AbstractContainer { ...@@ -147,7 +168,13 @@ 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'];
if (!empty($flexFormFieldArray['TCEforms']['config']['renderType'])) {
$options['renderType'] = $flexFormFieldArray['TCEforms']['config']['renderType'];
} else {
// Fallback to type if no renderType is given
$options['renderType'] = $flexFormFieldArray['TCEforms']['config']['type'];
}
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$childResult = $nodeFactory->create($options)->render(); $childResult = $nodeFactory->create($options)->render();
......
...@@ -99,13 +99,13 @@ class FlexFormLanguageContainer extends AbstractContainer { ...@@ -99,13 +99,13 @@ class FlexFormLanguageContainer extends AbstractContainer {
$options['flexFormCurrentLanguage'] = $flexFormCurrentLanguage; $options['flexFormCurrentLanguage'] = $flexFormCurrentLanguage;
$options['flexFormNoEditDefaultLanguage'] = $flexFormNoEditDefaultLanguage; $options['flexFormNoEditDefaultLanguage'] = $flexFormNoEditDefaultLanguage;
if (!$hasTabs) { if (!$hasTabs) {
$options['type'] = 'flexFormNoTabsContainer'; $options['renderType'] = 'flexFormNoTabsContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$flexFormNoTabsResult = $nodeFactory->create($options)->render(); $flexFormNoTabsResult = $nodeFactory->create($options)->render();
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $flexFormNoTabsResult); $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $flexFormNoTabsResult);
} else { } else {
$options['type'] = 'flexFormTabsContainer'; $options['renderType'] = 'flexFormTabsContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$flexFormTabsContainerResult = $nodeFactory->create($options)->render(); $flexFormTabsContainerResult = $nodeFactory->create($options)->render();
......
...@@ -78,7 +78,7 @@ class FlexFormNoTabsContainer extends AbstractContainer { ...@@ -78,7 +78,7 @@ class FlexFormNoTabsContainer extends AbstractContainer {
$options['flexFormFormPrefix'] = '[data][' . $flexFormSheetNameInRowData . '][' . $flexFormCurrentLanguage . ']'; $options['flexFormFormPrefix'] = '[data][' . $flexFormSheetNameInRowData . '][' . $flexFormCurrentLanguage . ']';
$options['parameterArray'] = $parameterArray; $options['parameterArray'] = $parameterArray;
$options['type'] = 'flexFormElementContainer'; $options['renderType'] = 'flexFormElementContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
return $nodeFactory->create($options)->render(); return $nodeFactory->create($options)->render();
......
...@@ -76,7 +76,7 @@ class FlexFormSectionContainer extends AbstractContainer { ...@@ -76,7 +76,7 @@ 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'];
$options['type'] = 'flexFormContainerContainer'; $options['renderType'] = 'flexFormContainerContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$flexFormContainerContainerResult = $nodeFactory->create($options)->render(); $flexFormContainerContainerResult = $nodeFactory->create($options)->render();
...@@ -105,7 +105,7 @@ class FlexFormSectionContainer extends AbstractContainer { ...@@ -105,7 +105,7 @@ class FlexFormSectionContainer extends AbstractContainer {
$options['flexFormContainerCounter'] = $flexFormFieldIdentifierPrefix . '-form'; $options['flexFormContainerCounter'] = $flexFormFieldIdentifierPrefix . '-form';
$options['flexFormContainerTitle'] = $sectionTitle; $options['flexFormContainerTitle'] = $sectionTitle;
$options['flexFormContainerElementCollapsed'] = FALSE; $options['flexFormContainerElementCollapsed'] = FALSE;
$options['type'] = 'flexFormContainerContainer'; $options['renderType'] = 'flexFormContainerContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$flexFormContainerContainerTemplateResult = $nodeFactory->create($options)->render(); $flexFormContainerContainerTemplateResult = $nodeFactory->create($options)->render();
......
...@@ -92,7 +92,7 @@ class FlexFormTabsContainer extends AbstractContainer { ...@@ -92,7 +92,7 @@ class FlexFormTabsContainer extends AbstractContainer {
'tab', 'tab',
$tabIdString . '-' . $tabCounter, $tabIdString . '-' . $tabCounter,
); );
$options['type'] = 'flexFormElementContainer'; $options['renderType'] = 'flexFormElementContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$childReturn = $nodeFactory->create($options)->render(); $childReturn = $nodeFactory->create($options)->render();
......
...@@ -99,17 +99,18 @@ class FullRecordContainer extends AbstractContainer { ...@@ -99,17 +99,18 @@ class FullRecordContainer extends AbstractContainer {
$options['fieldsArray'] = $fieldsArray; $options['fieldsArray'] = $fieldsArray;
// Palettes may contain elements that should be excluded, resolved in PaletteContainer // Palettes may contain elements that should be excluded, resolved in PaletteContainer
$options['excludeElements'] = $excludeElements; $options['excludeElements'] = $excludeElements;
$options['recordTypeValue'] = $recordTypeValue;
$options['defaultLanguageData'] = $this->defaultLanguageData; $options['defaultLanguageData'] = $this->defaultLanguageData;
$options['defaultLanguageDataDiff'] = $this->defaultLanguageDataDiff; $options['defaultLanguageDataDiff'] = $this->defaultLanguageDataDiff;
$options['additionalPreviewLanguageData'] = $this->additionalPreviewLanguageData; $options['additionalPreviewLanguageData'] = $this->additionalPreviewLanguageData;
if ($hasTabs) { if ($hasTabs) {
$options['type'] = 'tabsContainer'; $options['renderType'] = 'tabsContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$resultArray = $nodeFactory->create($options)->render(); $resultArray = $nodeFactory->create($options)->render();
} else { } else {
$options['type'] = 'noTabsContainer'; $options['renderType'] = 'noTabsContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$resultArray = $nodeFactory->create($options)->render(); $resultArray = $nodeFactory->create($options)->render();
......
...@@ -223,7 +223,7 @@ class InlineControlContainer extends AbstractContainer { ...@@ -223,7 +223,7 @@ 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();
$options['type'] = 'inlineRecordContainer'; $options['renderType'] = 'inlineRecordContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$childArray = $nodeFactory->create($options)->render(); $childArray = $nodeFactory->create($options)->render();
......
...@@ -217,7 +217,7 @@ class InlineRecordContainer extends AbstractContainer { ...@@ -217,7 +217,7 @@ class InlineRecordContainer extends AbstractContainer {
$domObjectId . '-' . $table . '-' . $row['uid'], $domObjectId . '-' . $table . '-' . $row['uid'],
); );
$options['overruleTypesArray'] = $overruleTypesArray; $options['overruleTypesArray'] = $overruleTypesArray;
$options['type'] = 'fullRecordContainer'; $options['renderType'] = 'fullRecordContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
return $nodeFactory->create($options)->render(); return $nodeFactory->create($options)->render();
......
...@@ -72,7 +72,7 @@ class ListOfFieldsContainer extends AbstractContainer { ...@@ -72,7 +72,7 @@ class ListOfFieldsContainer extends AbstractContainer {
$options = $this->globalOptions; $options = $this->globalOptions;
$options['fieldsArray'] = $finalFieldsConfiguration; $options['fieldsArray'] = $finalFieldsConfiguration;
$options['type'] = 'paletteAndSingleContainer'; $options['renderType'] = 'paletteAndSingleContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
return $nodeFactory->create($options)->render(); return $nodeFactory->create($options)->render();
......
...@@ -32,7 +32,7 @@ class NoTabsContainer extends AbstractContainer { ...@@ -32,7 +32,7 @@ class NoTabsContainer extends AbstractContainer {
*/ */
public function render() { public function render() {
$options = $this->globalOptions; $options = $this->globalOptions;
$options['type'] = 'paletteAndSingleContainer'; $options['renderType'] = 'paletteAndSingleContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$resultArray = $nodeFactory->create($options)->render(); $resultArray = $nodeFactory->create($options)->render();
......
...@@ -135,9 +135,8 @@ class PaletteAndSingleContainer extends AbstractContainer { ...@@ -135,9 +135,8 @@ class PaletteAndSingleContainer extends AbstractContainer {
$options = $this->globalOptions; $options = $this->globalOptions;
$options['fieldName'] = $fieldName; $options['fieldName'] = $fieldName;
$options['fieldExtra'] = $fieldConfiguration['fieldExtra'];
$options['type'] = 'singleFieldContainer'; $options['renderType'] = 'singleFieldContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$childResultArray = $nodeFactory->create($options)->render(); $childResultArray = $nodeFactory->create($options)->render();
...@@ -259,9 +258,8 @@ class PaletteAndSingleContainer extends AbstractContainer { ...@@ -259,9 +258,8 @@ class PaletteAndSingleContainer extends AbstractContainer {
} }
$options = $this->globalOptions; $options = $this->globalOptions;
$options['fieldName'] = $fieldName; $options['fieldName'] = $fieldName;
$options['fieldExtra'] = $fieldArray['fieldExtra'];
$options['type'] = 'singleFieldContainer'; $options['renderType'] = 'singleFieldContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$singleFieldContentArray = $nodeFactory->create($options)->render(); $singleFieldContentArray = $nodeFactory->create($options)->render();
......
...@@ -19,6 +19,7 @@ use TYPO3\CMS\Backend\Form\NodeFactory; ...@@ -19,6 +19,7 @@ use TYPO3\CMS\Backend\Form\NodeFactory;
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\Backend\Form\Utility\FormEngineUtility; use TYPO3\CMS\Backend\Form\Utility\FormEngineUtility;
use TYPO3\CMS\Core\Utility\ArrayUtility;
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\Utility\IconUtility; use TYPO3\CMS\Backend\Utility\IconUtility;
...@@ -56,9 +57,19 @@ class SingleFieldContainer extends AbstractContainer { ...@@ -56,9 +57,19 @@ class SingleFieldContainer extends AbstractContainer {
} }
$parameterArray = array(); $parameterArray = array();
$parameterArray['extra'] = $this->globalOptions['fieldExtra'];
$parameterArray['fieldConf'] = $GLOBALS['TCA'][$table]['columns'][$fieldName]; $parameterArray['fieldConf'] = $GLOBALS['TCA'][$table]['columns'][$fieldName];
// Overlay fieldConf with possible defined columnsOverrides of given record type
$recordTypeValue = $this->globalOptions['recordTypeValue'];
// Hint: 0 is a valid $recordTypeValue, !empty() does not work here
if (trim($recordTypeValue) !== '' && is_array($GLOBALS['TCA'][$table]['types'][$recordTypeValue]['columnsOverrides'][$fieldName])) {
// Merge columnsOverrides of this field over existing field configuration
ArrayUtility::mergeRecursiveWithOverrule(
$parameterArray['fieldConf'],
$GLOBALS['TCA'][$table]['types'][$recordTypeValue]['columnsOverrides'][$fieldName]
);
}
// A couple of early returns in case the field should not be rendered // A couple of early returns in case the field should not be rendered
// Check if this field is configured and editable according to exclude fields and other configuration // Check if this field is configured and editable according to exclude fields and other configuration
if ( if (
...@@ -159,7 +170,12 @@ class SingleFieldContainer extends AbstractContainer { ...@@ -159,7 +170,12 @@ class SingleFieldContainer extends AbstractContainer {
$options = $this->globalOptions; $options = $this->globalOptions;
$options['parameterArray'] = $parameterArray; $options['parameterArray'] = $parameterArray;
$options['elementBaseName'] = $newElementBaseName; $options['elementBaseName'] = $newElementBaseName;
$options['type'] = $parameterArray['fieldConf']['config']['type']; if (!empty($parameterArray['fieldConf']['config']['renderType'])) {
$options['renderType'] = $parameterArray['fieldConf']['config']['renderType'];
} else {
// Fallback to type if no renderType is given
$options['renderType'] = $parameterArray['fieldConf']['config']['type'];
}
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$resultArray = $nodeFactory->create($options)->render(); $resultArray = $nodeFactory->create($options)->render();
...@@ -252,7 +268,7 @@ class SingleFieldContainer extends AbstractContainer { ...@@ -252,7 +268,7 @@ 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);
$options['type'] = 'none'; $options['renderType'] = 'none';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$noneElementResult = $nodeFactory->create($options)->render(); $noneElementResult = $nodeFactory->create($options)->render();
......
...@@ -68,9 +68,9 @@ class SoloFieldContainer extends AbstractContainer { ...@@ -68,9 +68,9 @@ class SoloFieldContainer extends AbstractContainer {
if ($GLOBALS['TCA'][$table]['columns'][$fieldName]) { if ($GLOBALS['TCA'][$table]['columns'][$fieldName]) {
$options = $this->globalOptions; $options = $this->globalOptions;
$options['fieldName'] = $fieldName; $options['fieldName'] = $fieldName;
$options['fieldExtra'] = $fieldConfiguration['fieldExtra']; $options['recordTypeValue'] = $recordTypeValue;
$options['type'] = 'singleFieldContainer'; $options['renderType'] = 'singleFieldContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$resultArray = $nodeFactory->create($options)->render(); $resultArray = $nodeFactory->create($options)->render();
......
...@@ -86,7 +86,7 @@ class TabsContainer extends AbstractContainer { ...@@ -86,7 +86,7 @@ class TabsContainer extends AbstractContainer {
foreach ($elements as $element) { foreach ($elements as $element) {
$options['fieldsArray'][] = implode(';', $element); $options['fieldsArray'][] = implode(';', $element);
} }
$options['type'] = 'paletteAndSingleContainer'; $options['renderType'] = 'paletteAndSingleContainer';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$childArray = $nodeFactory->create($options)->render(); $childArray = $nodeFactory->create($options)->render();
......
...@@ -435,7 +435,7 @@ abstract class AbstractFormElement extends AbstractNode { ...@@ -435,7 +435,7 @@ abstract class AbstractFormElement extends AbstractNode {
), ),
'itemFormElValue' => $PA['itemFormElValue'], 'itemFormElValue' => $PA['itemFormElValue'],
); );
$options['type'] = 'none'; $options['renderType'] = 'none';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
$noneElementResult = $nodeFactory->create($options)->render(); $noneElementResult = $nodeFactory->create($options)->render();
......
...@@ -62,7 +62,7 @@ class GroupElement extends AbstractFormElement { ...@@ -62,7 +62,7 @@ class GroupElement extends AbstractFormElement {
$noDelete = isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'delete'); $noDelete = isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'delete');
// "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist. // "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist.
$specConf = BackendUtility::getSpecConfParts($parameterArray['extra'], $parameterArray['fieldConf']['defaultExtras']); $specConf = BackendUtility::getSpecConfParts($parameterArray['fieldConf']['defaultExtras']);
// Register properties in requiredElements // Register properties in requiredElements
$resultArray['requiredElements'][$parameterArray['itemFormElName']] = array( $resultArray['requiredElements'][$parameterArray['itemFormElName']] = array(
......
...@@ -76,7 +76,7 @@ class ImageManipulationElement extends AbstractFormElement { ...@@ -76,7 +76,7 @@ class ImageManipulationElement extends AbstractFormElement {
), ),
'itemFormElValue' => $parameterArray['itemFormElValue'], 'itemFormElValue' => $parameterArray['itemFormElValue'],
); );
$options['type'] = 'none'; $options['renderType'] = 'none';
/** @var NodeFactory $nodeFactory */ /** @var NodeFactory $nodeFactory */
$nodeFactory = $this->globalOptions['nodeFactory']; $nodeFactory = $this->globalOptions['nodeFactory'];
return $nodeFactory->create($options)->render(); return $nodeFactory->create($options)->render();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment