Breaking: #102935 - Overhauled extension installation in Extension Manager

See forge#102935

Description

Installing extensions via the extension manager is only used for non-Composer-based installations. However, there have been a couple of dependencies to the EXT:extensionmanager, which required even Composer-based installations to have this extension installed. This has now been resolved. The EXT:extensionmanager extension is now optional.

The public \TYPO3\CMS\Extensionmanager\Utility\InstallUtility->processExtensionSetup() method has therefore been removed. It has previously been used to execute a couple of "import" tasks, such as import site configurations or media assets to the fileadmin/. However those tasks had dependencies to other optional core extensions, such as EXT:impexp. Therefore the new PSR-14 event PackageInitializationEvent has been introduced and the functionality has been split into corresponding event listeners, which are added to their associated Core extensions.

The PSR-14 events, dispatched by those "tasks" have been removed:

  • \TYPO3\CMS\Extensionmanager\Event\AfterExtensionDatabaseContentHasBeenImportedEvent

  • \TYPO3\CMS\Extensionmanager\Event\AfterExtensionFilesHaveBeenImportedEvent

  • \TYPO3\CMS\Extensionmanager\Event\AfterExtensionSiteFilesHaveBeenImportedEvent

  • \TYPO3\CMS\Extensionmanager\Event\AfterExtensionStaticDatabaseContentHasBeenImportedEvent

The information, provided by those events can now be accessed by fetching the corresponding storage entry from the new \TYPO3\CMS\Core\Package\Event\PackageInitializationEvent.

Using before and after keywords in the listener registration, custom extensions can ensure to be executed, once the corresponding information is available.

It's even possible to manually execute those "tasks" by dispatching the PackageInitializationEvent in custom extension code. This can be used as replacement for the InstallUtility->processExtensionSetup() call.

Impact

Using one of the removed PSR-14 events or calling the removed method will lead to a PHP error. The extension scanner will report any usages.

Affected installations

TYPO3 installations with extensions registering listeners to the removed events or calling the removed method in their extension code.

Migration

Instead of registering listeners for the removed events, developers can now just register a listener to the new PackageInitializationEvent, which contains the listeners result as storage entry:

// Before

#[AsEventListener]
public function __invoke(AfterExtensionSiteFilesHaveBeenImportedEvent $event): void
{
    foreach ($event->getSiteIdentifierList() as $siteIdentifier) {
        $configuration = $this->siteConfiguration->load($siteIdentifier);
        $configuration = $this->extendSiteConfiguration($configuration);
        $this->siteConfiguration->write($siteIdentifier, $configuration);
    }
}

// After

#[AsEventListener(after: ImportSiteConfigurationsOnPackageInitialization::class)]
public function __invoke(PackageInitializationEvent $event): void
{
    foreach ($event->getStorageEntry(ImportSiteConfigurationsOnPackageInitialization::class)->getResult() as $siteIdentifier) {
        $configuration = $this->siteConfiguration->load($siteIdentifier);
        $configuration = $this->extendSiteConfiguration($configuration);
        $this->siteConfiguration->write($siteIdentifier, $configuration);
    }
}

Instead of calling InstallUtility->processExtensionSetup(), extensions can just dispatch the PackageInitializationEvent on their own.