Photo of Torben Hansen

A TechBlog by Torben Hansen


Freelance Full Stack Web Developer located in Germany.
I create web applications mainly using TYPO3, PHP, Python and JavaScript.
Home Archive Tags

How to add a replacement for the removed TCA Option "setToDefaultOnCopy" in TYPO3 10.4

⚠️ Update 17.10.2024: With TYPO3 v13 and the TCA Schema, the following "hack" is not possible anymore, since TCA is readonly for the required DataHandler operations. A possible workaround is to mark non deleted inline subrecords as deleted in `processCmdmap_preProcess` and to revert the process in `processCmdmap_postProcess`. This will requires an extra field in the database table.

The TYPO3 TCA Option “setToDefaultOnCopy” has been removed in TYPO3 10 in order to reduce the amount of checks in DataHandler and the amount of available options in TCA. The documentation says, that “This option was only there for resetting some `sys_action` values to default, which can easily be achieved by a hook if needed. If an extension author uses this setting,
this should be achieved with proper DataHandler hooks.”
I use this option in one of my extensions. Basically, I have one “main” record, that has one Inline field with various “ subrecords”. Those “subrecords” are user generated and should not be copied, when the main record is copied, so I had to find out which DataHandler hooks should be used to get the removed functionality back for the TYPO3 10 compatible version of my extension.

After some hours with several breakpoints in the TYPO3 DataHandler I came to the conclusion, that this may not be as “ easy” as described, since there is no Hook, where you can unset certain field values during the copy (or localize) process. And if there was, then another problem would have shown up, since relation fields are processed different ( basically the relation is resolved using TCA) on copy or translation commands in DataHandler.

Knowing the last about TCA however makes it possible to hook into the process. At a very early stage in DataHandler, I use processCmdmap_preProcess to set the TCA type for affected fields to “none” as shown below:

public function processCmdmap_preProcess($command, $table, $id, $value, $pObj, $pasteUpdate)
{
    if (in_array($command, ['copy', 'localize']) && $table === 'tx_extension_table') {
        $GLOBALS['TCA']['tx_extension_table']['columns']['fieldname1']['config']['type'] = 'none';
        $GLOBALS['TCA']['tx_extension_table']['columns']['fieldname2']['config']['type'] = 'none';
    }
}

With this configuration in TCA, the affected fields are completely ignored by the copy/localize command in DataHandler. It is now just important to change the field types back after the command is finished in processCmdmap_postProcess hook as shown below:

public function processCmdmap_postProcess($command, $table, $id, $value, $pObj, $pasteUpdate, $pasteDatamap)
{
    if (in_array($command, ['copy', 'localize']) && $table === 'tx_extension_table') {
        $GLOBALS['TCA']['tx_extension_table']['columns']['fieldname1']['config']['type'] = 'text';
        $GLOBALS['TCA']['tx_extension_table']['columns']['fieldname2']['config']['type'] = 'inline';
    }
}

Hard to say, if this is a good approach to get the functionality back. It feels not really right to change existing TCA at runtime as shown, but at least, I could not find any downsides in the solution and it works fine for me.