Switchable controller actions have been a core concept in TYPO3 for quite some time, allowing integrators and developers to define flexible behaviors for their plugins. However, when upgrading or restructuring extensions, especially in projects that have evolved over time, you may need to migrate existing flexform settings to align them with new list types or changed controller-action definitions.
In this tutorial, we’ll explore a straightforward way to handle such a migration without manually tweaking each record. By the end of this article, you’ll have a clear understanding of how to create and register a custom Upgrade Wizard class to automatically migrate your existing switchable controller actions to new list types.
Why You Might Need This Migration
1. Refactoring or Renaming Controller Actions
As your extension evolves, you might rename or reorganize controller actions. This can break the connection between the existing flexform switchableControllerActions and your newly refactored controllers.
2. Changing Plugins / List Types
In TYPO3, the “list_type” defines which plugin is used by a content element. If you introduce a new plugin or rename an existing one, you need to ensure all references in tt_content are updated properly.
3. Easier Upgrade Path
Instead of manually editing every content element in the backend, a custom migration script ensures a clean and automated approach. This also reduces human error and provides a repeatable process for future migrations.
Overview of the Steps
1. Create Your Migration Class
Build an Upgrade Wizard that finds and updates all records in tt_content based on old switchableControllerActions references.
2. Register Your Upgrade Wizard
Make TYPO3 aware of your new migration class by adding it to ext_localconf.php under the SC_OPTIONS array.
3. Run the Upgrade Wizard
Through the TYPO3 Install Tool or Maintenance Area, trigger the wizard and complete the migration seamlessly.
Step 1: Create the SwitchableControllerActions Migration Class
Below is a sample migration script you can adapt to your extension’s specific needs. Make sure to adjust the namespace and the constants for your particular project. This simple approach checks for records in tt_content with matching switchableControllerActions and updates their list_type accordingly.
<?php
declare(strict_types=1);
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
final class SwitchableUpgradeWizard implements UpgradeWizardInterface
{
private const MIGRATION_SETTINGS = [
[
'switchableControllerActions' => 'switchableControllerActions type',
'targetListType' => 'new list type',
],
[
'switchableControllerActions' => 'switchableControllerActions type',
'targetListType' => 'new list type',
],
];
/**
* Return the identifier for this wizard
*/
public function getIdentifier(): string
{
return 'myExtension_exampleUpgradeWizard';
}
/**
* Return the speaking name of this wizard
*/
public function getTitle(): string
{
return 'switchableControllerActions migration';
}
/**
* Return the description for this wizard
*/
public function getDescription(): string
{
return 'migration script for switchableControllerActions';
}
/**
* Execute the update
*/
public function executeUpdate(): bool
{
$success = false;
try {
foreach (self::MIGRATION_SETTINGS as $listType) {
$success = $this->getMigrationRecords($listType);
}
} catch (\Throwable $th) {
return false;
}
return $success;
}
/**
* Is an update necessary?
*/
public function updateNecessary(): bool
{
// You could add logic here to check if any records need migration
return true;
}
/**
* Returns an array of class names of prerequisite classes
*/
public function getPrerequisites(): array
{
return [];
}
/**
* Just a placeholder in case you need extra migration logic
*/
public function performMigration(): bool
{
return true;
}
/**
* Updates tt_content records that match the old switchableControllerActions
*/
protected function getMigrationRecords(array $listType): bool
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('tt_content');
try {
$queryBuilder
->update('tt_content')
->where(
$queryBuilder->expr()->like(
'pi_flexform',
$queryBuilder->createNamedParameter(
'%' . $queryBuilder->escapeLikeWildcards($listType['switchableControllerActions']) . '%'
)
)
)
->set('list_type', $listType['targetListType'])
->executeStatement();
return true;
} catch (\Throwable $th) {
return false;
}
}
}
Key Points in This Class
1. getIdentifier(): Must match the registration key in ext_localconf.php.
2. MIGRATION_SETTINGS: An array of mappings between your old switchable action references and the new list_type you want.
3.executeUpdate(): Loops through the array and processes each mapping.
4. getMigrationRecords(): The heart of the script, updating tt_content records where pi_flexform contains the specified string.
Feel free to expand the logic in performMigration() or executeUpdate() if you have additional tasks, such as updating different database fields or cleaning up additional data.
Step 2: Register Your Upgrade Wizard in ext_localconf.php
Once you have created the migration class, you need to make TYPO3 aware of it. Open (or create) your ext_localconf.php file in your extension and add the following snippet. Make sure the namespace (for example, \Vender\Extension\Upgrades\SwitchableUpgradeWizard::class) matches the actual location of your PHP class.
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update']['myExtension_exampleUpgradeWizard']
= \Vender\Extension\Upgrades\SwitchableUpgradeWizard::class;
This registration tells TYPO3 that there is a new upgrade wizard identified by myExtension_exampleUpgradeWizard. When you go to the Install Tool > Upgrade Wizard, you will see this wizard available to run.
Step 3: Running the Migration
1. Access the Install Tool (or Maintenance Area):
Log into your TYPO3 backend and navigate to the “System Maintenance” or “Upgrade” section, depending on your TYPO3 version.
2. Find Your Wizard in the Upgrade List:
Search for the title “switchableControllerActions migration” or whatever you specified in getTitle().
3. Execute the Wizard:
Click the “Execute” button (the naming may differ slightly depending on TYPO3 version). The script will look for all tt_content records containing the old switchableControllerActions references and update their list_type fields accordingly.
Verification
After running the upgrade wizard, it’s good practice to verify that:
Your flexform data is still intact.
The new plugin or list type is displayed correctly in the backend.
Frontend functionality continues to work as expected with the updated controller actions.
If you have a large site, you might want to test this script on a staging or development instance first, ensuring you don’t accidentally break any content.
Conclusion
Migrating switchable controller actions is a vital task when you’re reorganizing or renaming your TYPO3 extensions. By creating a custom Upgrade Wizard, you can handle this process more efficiently, ensuring a smooth transition from old controller-action references to updated ones. This not only saves you time but also keeps your system clean and consistent.
Feel free to adjust the snippets above to fit your own extension’s namespace and class structures. Once you get the hang of it, you’ll realize how powerful and flexible TYPO3’s upgrade wizards can be for all sorts of migrations.
Have any questions or suggestions on how to further simplify switchable controller action migrations? Reach out to us at T3Planet—where we’re always happy to discuss TYPO3 tips, tricks, and best practices!
Happy Upgrading & Happy TYPO3!
Post a Comment