content-blocks icon indicating copy to clipboard operation
content-blocks copied to clipboard

Destructive DB schema update removes typeField from RecordTypes

Open ri-klein opened this issue 9 months ago • 6 comments

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.

ri-klein avatar Apr 29 '24 11:04 ri-klein