Feature: #103581 - Automatically transform TCA field values for Record objects

See forge#103581

Description

With forge#103783 the new Record object has been introduced. It's an object representing a raw database record, based on TCA and is usually used in the frontend (via Fluid Templates), when fetching records with the RecordTransformationDataProcessor (record-transformation) or by collecting content elements with the PageContentFetchingProcessor (page-content).

The Records API - introduced together with the Schema API in forge#104002 - now expands the Records's values for most common field types (known from the TCA Schema) from their raw database value into "rich-flavored" values, which might be Record, FileReference, Folder or \DateTimeImmutable objects.

This works for the following "relation" TCA types:

  • category
  • file
  • folder
  • group
  • inline
  • select with MM and foreign_table

In addition, the values of following TCA types are also resolved and expanded automatically:

  • datetime
  • flex
  • json
  • link
  • select with a static list of entries

Each of the fields receives a full-fledged resolved value, based on the field configuration from TCA.

In case of relations (category, group, inline, select with MM and foreign_table), a collection (LazyRecordCollection) of new Record objects is attached as value. In case of file, a collection (LazyFileReferenceCollection) of FileReference objects and in case of type folder, a collection (LazyFolderCollection) of Folder objects are attached.

Example

<f:for each="{myContent.main.records}" as="record">
    <f:for each="{record.image}" as="image">
        <f:image image="{image}" />
    </f:for>
</f:for>
Copied!

New TCA option relationship

In order to define cardinality on TCA level, the option relationship is introduced for all "relation" TCA types listed above. If this option is set to oneToOne or manyToOne, then relations are resolved directly without being wrapped into collection objects. In case the relation can not be resolved, NULL is returned.

'image' => [
    'config' => [
        'type' => 'file',
        'relationship' => 'manyToOne',
    ]
]
Copied!
<f:for each="{myContent.main.records}" as="record">
    <f:image image="{record.image}" />
</f:for>
Copied!

Field expansion

For TCA type flex, the corresponding FlexForm is resolved and therefore all values within this FlexForm are processed and expanded as well.

Fields of TCA type datetime will be transformed into a full \DateTimeInterface object.

Fields of TCA type json will provide the decoded JSON value.

Fields of TCA type link will provide the TypolinkParameter object, which is an object oriented representation of the corresponding TypoLink parameter configuration.

Fields of TCA type select without a relationship will always provide an array of static values.

Impact

When using Record objects through the RecordFactory API, e.g. via RecordTransformationDataProcessor (record-transformation) or PageContentFetchingProcessor (page-content), the corresponding Record objects are now automatically processed and enriched.

Those can not only be used in the frontend but also for Backend Previews in the page module. This is possible by configuring a Fluid Template via Page TSconfig to be used for the page preview rendering:

mod.web_layout.tt_content.preview {
    textmedia = EXT:site/Resources/Private/Templates/Preview/Textmedia.html
}
Copied!

In such template the newly available variable {record} can be used to access the resolved field values. It is advised to migrate existing preview templates to this new object, as the former values will probably vanish in the next major version.

By utilizing the new API for fetching records and content elements, the need for further data processors, e.g. FilesProcessor (files), becomes superfluous since all relations are resolved automatically when requested.