content-blocks
content-blocks copied to clipboard
Destructive DB schema update removes typeField from RecordTypes
Hello,
I noticed a weird behaviour when calling the CLI command database:updateschema destructive
(from helhum/typo3-console). The command wants to delete the typeField from a custom multi-type RecordType (if the table is auto-generated by content-blocks). This does not happen when calling the CLI command immediately after flushing all caches; Only after caches have been built (e.g. after executing a page request).
The issue can be reproduced with e.g. the diver/instructor multi-type record example from the documentation (tested on TYPO3 12.4.14 with content-blocks 0.7.5):
- Flush caches
- Immediately call
typo3 database:updateschema destructive -v --dry-run
- Nothing happens
- Call
typo3 database:updateschema destructive -v --dry-run
again - Removing the type field should be on the schema update list
I did some research on why that happens: During the execution of the CLI command, the event TYPO3\CMS\Core\Database\Event\AlterTableDefinitionStatementsEvent
gets fired, which causes \TYPO3\CMS\ContentBlocks\Generator\SqlGenerator
to get invoked.
Here, TYPO3\CMS\ContentBlocks\Definition\Factory\TableDefinitionCollectionFactory::createUncached
gets called, which in turn calls TYPO3\CMS\ContentBlocks\Definition\Factory\ContentBlockCompiler::compile
.
Immediately after flushing caches, $GLOBALS['TCA']
does not contain a definition for the RecordType; After building the caches however, it does contain a definition. \TYPO3\CMS\ContentBlocks\Definition\Factory\ContentBlockCompiler::prepareYaml
then treats the typeField as an existing field (as \TYPO3\CMS\ContentBlocks\Schema\SimpleTcaSchemaFactory::has
then wrongly returns true).
The resulting mergedTableDefinitions
for ['TABLENAME']['fields']['TYPE_FIELD']['config']
then contains useExistingField = true
, which means that in \TYPO3\CMS\ContentBlocks\Definition\TableDefinition::createFromTableArray
, when \TYPO3\CMS\ContentBlocks\Definition\SqlColumnDefinitionCollection::createFromArray
gets called, the column gets skipped and is missing from the table definition... which then causes database:updateschema destructive
to remove the column.
I hope this helps you a bit on narrowing down the cause of the issue.