Important: The FlexForm upgrade wizard migrates records
Description
The upgrade wizard academic
(FGTCLB\) never migrated a
single content element. It built the WHERE constraint of its UPDATE
statement on the query builder of the enclosing SELECT:
$updateQueryBuilder->update('tt_content')
->set('pi_flexform', $this->array2xml($flexFormData))
->where(
$queryBuilder->expr()->in( // select builder
'uid',
$queryBuilder->createNamedParameter($record['uid'], …) // select builder
)
)
->executeStatement();
A named parameter is bound to the query builder that created it, so the
statement carried a placeholder whose value was never bound to it. At the same
time
set had created a placeholder of its own on the update builder,
holding the new FlexForm XML. The first record therefore ran
UPDATE tt_content SET pi_flexform = :dcValue1 WHERE uid IN (:dcValue1)
comparing the XML against uid, and every following record referred to a
placeholder that did not exist on the update builder at all.
The constraint is now built on the builder that executes it, with eq since
the value is always a single uid:
->where(
$updateQueryBuilder->expr()->eq(
'uid',
$updateQueryBuilder->createNamedParameter($record['uid'], Connection::PARAM_INT)
)
)
Impact
The wizard now performs the FlexForm migration it announces:
settings., the name 1.x stored, becomes
settings. (value 1 maps to active, anything else to all),
see Important: FlexForm upgrade wizard migrates the setting name of 1.x, settings. becomes
settings. and settings. becomes
settings., each keeping its value.
Previously the outcome depended on how many affected content elements existed:
- The first record compared the new FlexForm XML against
uid, because the placeholder of the update builder and the one of the select builder happened to carry the same name. MySQL, MariaDB and SQLite reported success and changed nothing, PostgreSQL aborted with aDoctrine\, invalid input syntax for integer.DBAL\ Exception\ Driver Exception - Every record after it referenced a placeholder that was never bound to the
update statement. Doctrine DBAL rejects such a statement before it reaches
the database, so the wizard aborted on every DBMS with a
Doctrine\, Named parameter "dcValueN" does not have a bound value.DBAL\ Array Parameters\ Exception\ Missing Named Parameter
Affected Installations
Installations that ran the upgrade wizard of a previous version. The plugin
FlexForm of academicprojects_ and
academicprojects_ content elements still carries the old
setting names, and the plugins fall back to their default behaviour for those
settings.
Migration
Run the upgrade wizard again. An installation that already executed it has it recorded as done, so it has to be marked undone first, in Admin Tools > Upgrade > Upgrade Wizard or, on TYPO3 v13, on the command line:
vendor/bin/typo3 upgrade:mark:undone academicProjects_flexFormUpgradeWizard
vendor/bin/typo3 upgrade:run academicProjects_flexFormUpgradeWizard
TYPO3 v12 has no command to mark a wizard undone. There it is marked undone in
the Install Tool, and upgrade: runs it afterwards.
Running it again is safe: the wizard only rewrites a FlexForm that still contains one of the old setting names and leaves every other record untouched.