Breaking: #107047 - Remove pointer field functionality of TCA flex
See forge#107047
Description
One of the main features of TCA are the record types. This allows using
a single table for different purposes and in different contexts. The most
well-known examples are the "Page Types" of the
pages
table and the
"Content Types" of the
tt_
table. For every specific type,
it's possible to define which fields to display and customize their
configuration.
A special case historically has been the plugin registration, which for a
long time used the so-called sub types feature of TCA. This was an
additional layer below record types, configured using
subtype_
(commonly list_
), and optionally
subtypes_
and subtypes_
to add or remove
fields depending on the selected subtype.
FlexForms attached to such subtypes were configured using
ds_
(typically pointing to list_
). This
came in combination with corresponding ds
configuration, which
was an array with keys combining the pointer fields, e.g.:
'ds_pointerField' => 'list_type,CType',
'ds' => [
'news_pi1,list' => 'FILE:EXT:news/Configuration/FlexForm.xml',
'default' => 'FILE:...'
],
Over recent TYPO3 versions, this approach has been deprecated in favor
of using record types exclusively for plugin registration via the
CType
field, making configuration cleaner and easier to understand.
The special plugin content element (CType=list
) and the corresponding plugin
subtype field list_
have been deprecated in Deprecation: #105076 - Plugin content element and plugin sub types
and have been removed in Breaking: #105377 - Deprecated functionality removed. You should also
check corresponding information regarding the usage of
Extension
and
Extension
, see Important: #105538 - list_type and sub types.
With this change, support for ds_
and the multi-entry ds
array
format has now been removed. The ds
option now points to a single FlexForm,
either directly or via a FILE:
reference.
FlexForms must instead be assigned via standard types
configuration
using columns
.
This also affects the "data structure identifier", which in the commonly used
"tca" type the data
, which is now set to default
in case the
table does not support record types or no record type specific configuration
exists. Otherwise the data
is set to the corresponding record
type value, e.g. textpic
.
This affects the related PSR-14 events:
\TYPO3\
CMS\ Core\ Configuration\ Event\ After Flex Form Data Structure Identifier Initialized Event \TYPO3\
CMS\ Core\ Configuration\ Event\ After Flex Form Data Structure Parsed Event \TYPO3\
CMS\ Core\ Configuration\ Event\ Before Flex Form Data Structure Identifier Initialized Event \TYPO3\
CMS\ Core\ Configuration\ Event\ Before Flex Form Data Structure Parsed Event
There is a fallback for v14 in place, resolving a comma-separated data
,
e.g. list_
to CType
.
To address circular dependencies during schema building,
Flex
has been enhanced to support both TCA Schema objects and raw TCA configuration
arrays as input. The following methods now accept a union type
array
for the new
$schema
parameter:
get
Data Structure Identifier () parse
Data Structure By Identifier () clean
Flex Form XML ()
These methods previously relied on
$GLOBALS
internally, which caused
architectural issues and is resolved now by working with the given schema directly.
Therefore, all calls to these methods should provide the
$schema
with either
a TcaSchema or raw TCA configuration array. However, since data structure resolution
can be customized by extensions, the
$schema
parameter is not strictly mandatory.
But, it is strongly recommended to provide it in most cases, as an
Invalid
will be thrown if schema resolution is required but no schema is passed.
This change further allows components like
Relation
to use
Flex
during schema building processes where only raw TCA is available.
For more details on the enhanced FlexFormTools functionality, see Feature: #107047 - FlexForm enhancements: Direct plugin registration and raw TCA support.
The following classes have been removed as they serve no further purpose:
\TYPO3\
CMS\ Core\ Configuration\ Flex Form\ Exception\ Invalid Combined Pointer Field Exception
Impact
FlexForm Pointer Field Removal
Any TCA definition that still uses ds_
or a ds
array with multiple entries (e.g., like news_
) will
no longer work and might cause errors on rendering.
FlexFormTools Schema Parameter
All code calling
Flex
methods (
get
,
parse
,
clean
) must be updated
to provide the required
$schema
parameter.
Affected installations
FlexForm Pointer Field Removal
All installations using ds_
and array-like structure for ds
in
their TCA type flex
configuration.
FlexFormTools Schema Parameter
All installations with custom code that directly calls
Flex
methods without providing the schema parameter. This includes custom extensions
or TYPO3 Core patches that use these methods directly.
A TcaMigration converts single-entry
ds
arrays automatically. Multi-entry
definitions require manual migration, since they have to be matched with the
correct record type configuration, which might require additional configuration
changes beforehand.
Example for the single-entry migration:
// before
'ds' => [
'default' => '<T3DataStructure>...',
],
// after
'ds' => '<T3DataStructure>...',
Migration
FlexForm Pointer Field Migration
Before:
'ds_pointerField' => 'list_type,CType',
'ds' => [
'news_pi1,list' => 'FILE:EXT:news/Configuration/FlexForm.xml',
'default' => '<T3DataStructure>...',
],
After:
'columns' => [
'pi_flexform' => [
'config' => [
'ds' => '<T3DataStructure>...',
],
],
],
'types' => [
'news_pi1' => [
'columnsOverrides' => [
'pi_flexform' => [
'config' => [
'ds' => 'FILE:EXT:news/Configuration/FlexForm.xml',
],
],
],
],
],
If no columns
is defined, the default ds
value of the field
configuration will be used, as usual behaviour.
FlexFormTools Schema Parameter Migration
Before:
$flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
$identifier = $flexFormTools->getDataStructureIdentifier(
$fieldTca,
'tt_content',
'pi_flexform',
$row
);
After:
$flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
// Option 1: Using TCA Schema object (recommended for normal usage)
$tcaSchema = $tcaSchemaFactory->get('tt_content');
$identifier = $flexFormTools->getDataStructureIdentifier(
$fieldTca,
'tt_content',
'pi_flexform',
$row,
$tcaSchema
);
// Option 2: Using raw TCA array (for schema building contexts)
$rawTca = $fullTca['tt_content'];
$identifier = $flexFormTools->getDataStructureIdentifier(
$fieldTca,
'tt_content',
'pi_flexform',
$row,
$rawTca
);