Feature: #102935 - PSR-14 event for package initialization functionality¶
See forge#102935
Description¶
A new PSR-14 event \TYPO3\CMS\Core\Package\Event\PackageInitializationEvent
has been introduced. It allows listeners to execute custom functionality after
a package has been activated. The event is therefore being dispatched at several
places, where packages get activated. Those are e.g. on extension installation
by the extension manager, or on calling the typo3 extension:setup
command. The
main component, dispatching the event however is the new
PackageActivationService
. The new service is a drop-in replacement for
the InstallUtility->install()
method, which is from now on just a wrapper
around PackageActivationService->activate()
. The wrapper is used to still
pass the current instance to listeners of the AfterPackageActivationEvent
.
TYPO3 already registers a couple of listeners to this event:
\TYPO3\CMS\Core\Package\Initialization\ImportExtensionDataOnPackageInitialization
\TYPO3\CMS\Core\Package\Initialization\ImportStaticSqlDataOnPackageInitialization
\TYPO3\CMS\Core\Package\Initialization\CheckForImportRequirements
\TYPO3\CMS\Impexp\Initialization\ImportContentOnPackageInitialization
\TYPO3\CMS\Impexp\Initialization\ImportSiteConfigurationsOnPackageInitialization
Developers are able to listen to the new event before or after TYPO3 Core
listeners have been executed, using before
and after
in the
listener registration. All listeners are able to store arbitrary data
in the Event using the addStorageEntry()
method. This is also used
by the core listeners to store their result, which was previously passed
to the removed
EXT:extensionmanager
PSR-14 events.
Listeners can access those information using corresponding getStorageEntry()
method. Those entries are a PackageInitializationResult
object, which
features the following methods:
getIdentifier()
- Returns the entry identifier, which is the listener service name for the TYPO3 Core listenersgetResult()
- Returns the result data, added by the corresponding listener
Using the new Event, listeners are equipped with following methods:
getExtensionKey()
- Returns the extension key for the activated packagegetPackage()
- Returns thePackageInterface
object of the activated packagegetContainer()
- Returns theContainerInterface
, used on activating the packagegetEmitter()
- Returns the emitter / the service, which has dispatched the eventhasStorageEntry()
- Whether a storage entry for a given identifier existsgetStorageEntry()
- Returns a storage entry for a given identifieraddStorageEntry()
- Adds a storage entry (PackageInitializationResult
) to the eventremoveStorageEntry()
- Removes a storage entry by a given identifier
Note
In case you have previously called InstallUtility->processExtensionSetup()
directly, you can now just dispatch the new event.
Example¶
The event listener class, using the PHP attribute #[AsEventListener]
for
registration, placing the listener after a specific core listener and adding
a storage entry, using the listener class name as identifier (which is
recommended and also done by TYPO3 Core):
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\Package\Event\PackageInitializationEvent;
use TYPO3\CMS\Core\Package\Initialization\ImportExtensionDataOnPackageInitialization;
final class PackageInitializationEventListener
{
#[AsEventListener(after: ImportExtensionDataOnPackageInitialization::class)]
public function __invoke(PackageInitializationEvent $event): void
{
if ($event->getExtensionKey() === 'my_ext') {
$event->addStorageEntry(__CLASS__, 'my result');
}
}
}
Impact¶
Using the new PSR-14 event, it's now possible to execute custom functionality when a package has been activated. Since TYPO3 Core also uses listeners to this event, custom extensions can easily place their functionality in between and fetch necessary information directly from the event's storage, instead of registering dedicated listeners.