Creating upgrade wizards¶
These steps create an upgrade wizard:
- Add a class implementing UpgradeWizardInterface
-
The class may implement other interfaces (optional):
- RepeatableInterface to not mark the wizard as done after execution
- ChattyInterface for generating output
Confirmable
for wizards that need user confirmationInferface
- Register the wizard in the file ext_localconf.php
UpgradeWizardInterface¶
Each upgrade wizard consists of a single PHP file containing a single PHP class.
This class has to implement \TYPO3\
and its methods:
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Upgrades;
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
final class ExampleUpgradeWizard implements UpgradeWizardInterface
{
/**
* Return the identifier for this wizard
* This should be the same string as used in the ext_localconf.php class registration
*/
public function getIdentifier(): string
{
return 'myExtension_exampleUpgradeWizard';
}
/**
* Return the speaking name of this wizard
*/
public function getTitle(): string
{
return 'Title of this updater';
}
/**
* Return the description for this wizard
*/
public function getDescription(): string
{
return 'Description of this updater';
}
/**
* Execute the update
*
* Called when a wizard reports that an update is necessary
*
* The boolean indicates whether the update was successful
*/
public function executeUpdate(): bool
{
// Add your logic here
}
/**
* Is an update necessary?
*
* Is used to determine whether a wizard needs to be run.
* Check if data for migration exists.
*
* @return bool Whether an update is required (TRUE) or not (FALSE)
*/
public function updateNecessary(): bool
{
// Add your logic here
}
/**
* Returns an array of class names of prerequisite classes
*
* This way a wizard can define dependencies like "database up-to-date" or
* "reference index updated"
*
* @return string[]
*/
public function getPrerequisites(): array
{
// Add your logic here
}
}
- Method
get
Identifier () - Return the identifier for this wizard. This should be the same string as
used in the
ext_
class registration.localconf. php - Method
get
Title () - Return the speaking name of this wizard.
- Method
get
Description () - Return the description for this wizard.
- Method
execute
Update () - Is called, if the user triggers the wizard. This method should contain, or call, the code that is needed to execute the upgrade. Return a boolean indicating whether the update was successful.
- Method
update
Necessary () - Is called to check whether the upgrade wizard has to run. Return
true
, if an upgrade is necessary,false
if not. Iffalse
is returned, the upgrade wizard will not be displayed in the list of available wizards. - Method
get
Prerequisites () -
Returns an array of class names of prerequisite classes. This way, a wizard can define dependencies before it can be performed. Currently, the following prerequisites exist:
Database
: Ensures that the database table fields are up-to-date.Updated Prerequisite Reference
: The reference index needs to be up-to-date.Index Updated Prerequisite
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite; use TYPO3\CMS\Install\Updates\ReferenceIndexUpdatedPrerequisite; /** * @return string[] */ public function getPrerequisites(): array { return [ DatabaseUpdatedPrerequisite::class, ReferenceIndexUpdatedPrerequisite::class, ]; }
Copied!
Registering wizards¶
Once the wizard is created, it needs to be registered. Registration is done in
ext_
:
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update']['myExtension_exampleUpgradeWizard']
= \MyVendor\MyExtension\Upgrades\ExampleUpgradeWizard::class;
Attention
Use the same identifier as key (here: my
),
which is returned by Upgrade
in your
wizard class.
Wizard identifier¶
The wizard identifier is used:
- when calling the wizard from the command line.
- when marking the wizard as done in the table
sys_
registry
Since all upgrade wizards of TYPO3 Core and extensions are registered using the
identifier as key in the global array
$GLOBALS
, it
is recommended to prepend the wizard identifier with a prefix based on the
extension key.
You should use the following naming convention for the identifier:
my
, for example bootstrap
- The extension key and wizard name in lowerCamelCase, separated by underscore
- The existing underscores in extension keys are replaced by capitalizing the following letter
Attention
Any identifier will still work, using these naming conventions is not
enforced. In fact, it is not recommended to change already existing wizard
identifiers: The information, that the wizard was performed is stored
using the identifier in the sys_
table and this information
would then be lost.
Some examples:
Extension key | Wizard identifier |
---|---|
container | container_upgradeColumnPositions |
news_events | newsEvents_migrateEvents |
bootstrap_package | bootstrapPackage_addNewDefaultTypes |
Marking wizard as done¶
As soon as the wizard has completely finished, for example, it detected that no upgrade is necessary anymore, the wizard is marked as done and will not be checked anymore.
To force TYPO3 to check the wizard every time, the interface EXT:install/Classes/Updates/RepeatableInterface.php (GitHub) has to be implemented. This interface works as a marker and does not force any methods to be implemented.
Generating output¶
The Chatty
can be implemented for wizards which should generate
output. EXT:install/Classes/Updates/ChattyInterface.php (GitHub) uses the Symfony
interface OutputInterface.
Classes using this interface must implement the following method:
/**
* Setter injection for output into upgrade wizards
*/
public function setOutput(OutputInterface $output): void;
The class EXT:install/Classes/Updates/DatabaseUpdatedPrerequisite.php (GitHub) implements this interface. We are showing a simplified example here, based on this class:
use Symfony\Component\Console\Output\OutputInterface;
class DatabaseUpdatedPrerequisite implements PrerequisiteInterface, ChattyInterface
{
/**
* @var OutputInterface
*/
protected $output;
public function setOutput(OutputInterface $output): void
{
$this->output = $output;
}
public function ensure(): bool
{
$adds = $this->upgradeWizardsService->getBlockingDatabaseAdds();
$result = null;
if (count($adds) > 0) {
$this->output->writeln('Performing ' . count($adds) . ' database operations.');
$result = $this->upgradeWizardsService->addMissingTablesAndFields();
}
return $result === null;
}
// ... more logic
}
Executing the wizard¶
Wizards are listed in the backend module Admin Tools > Upgrade and the card Upgrade Wizard. The registered wizard should be shown there, as long as it is not done.
It is also possible to execute the wizard from the command line:
vendor/bin/typo3 upgrade:run myExtension_exampleUpgradeWizard
typo3/sysext/core/bin/typo3 upgrade:run myExtension_exampleUpgradeWizard
Tip
Some existing wizards use the convention of using the fully-qualified class name as identifier. You may have to quote the backslashes in the shell, for example:
vendor/bin/typo3 upgrade:run '\\MyVendor\\MyExtension\\Upgrade\\ExampleUpgradeWizard'
typo3/sysext/core/bin/typo3 '\\MyVendor\\MyExtension\\Upgrade\\ExampleUpgradeWizard'
See also
You can find more information about running upgrade wizards in the Upgrade wizard section of the Installation Guide.