.. include:: /Includes.rst.txt .. _deprecation-108345-1774126701: ==================================================== Deprecation: #108345 - Deprecation of ext_emconf.php ==================================================== See :issue:`108345` Description =========== TYPO3 extensions that still ship an `ext_emconf.php` file **and** do not declare future compatibility to omit this file will now trigger a deprecation message during cache warm-up. With TYPO3 v15 the `ext_emconf.php` file is no longer evaluated. For TYPO3 classic (non-Composer) mode to keep working, TYPO3 then needs to know the extension version and which `require` and `suggest` entries are not TYPO3 extensions. The extension version and the `providesPackages` definition therefore become mandatory fields in `composer.json`, regardless of whether an `ext_emconf.php` file is still shipped. In TYPO3 v14 these fields are not yet mandatory, because the deprecated `ext_emconf.php` can still provide this information. A deprecation message is triggered only when the `version` or `providesPackages` field is missing, so that an extension can stay compatible with both TYPO3 v14 and v15 at the same time. To avoid this deprecation message, the extension must provide the required package metadata in `composer.json`. At minimum, this includes the extension version and the `providesPackages` definition: .. code-block:: json :caption: composer.json for an extension providing Composer packages { "name": "vendor/example", "type": "typo3-cms-extension", "description": "Example extension", "license": "GPL-2.0-or-later", "require": { "typo3/cms-core": "^14.2", "vendor/other-example": "*", "symfony/dotenv": "^8.0" }, "extra": { "typo3/cms": { "extension-key": "example_extension", "version": "1.0.0", "Package": { "providesPackages": { "symfony/dotenv": "Resources/Private/Php/ComposerVendor" } } } } } .. code-block:: json :caption: composer.json for an extension not providing Composer packages { "name": "vendor/example2", "type": "typo3-cms-extension", "description": "Example extension", "license": "GPL-2.0-or-later", "require": { "typo3/cms-core": "^14.2" }, "extra": { "typo3/cms": { "extension-key": "example2_extension", "version": "1.0.0", "Package": { "providesPackages": {} } } } } For compatibility with TYPO3 classic mode, third-party extensions must set the exact extension version in `extra.typo3/cms.version` or in the top level `version` field of :file:`composer.json`. This version must match the version previously defined in :file:`ext_emconf.php` and the released Git tag. Fixture extensions used in tests can set any version number, for example `1.0.0`, but a version number must still be provided to avoid deprecation messages. During testing, the version number is not evaluated. TYPO3 Core extensions may omit the version number in :file:`composer.json` because their version number is derived from :php-short:`\TYPO3\CMS\Core\Information\Typo3Version`. State migration --------------- The former `state` field from `ext_emconf.php` is deprecated as a source of extension metadata and should be set in `composer.json` using dedicated metadata instead. Supported stability values should be expressed via the version string: .. code-block:: json :caption: composer.json using version stability suffixes { "name": "vendor/example", "type": "typo3-cms-extension", "description": "Example extension", "extra": { "typo3/cms": { "extension-key": "example_extension", "version": "1.2.3-beta2", "Package": { "providesPackages": {} } } } } Supported Composer stability values are: * `dev` * `alpha` * `beta` * `RC` * `stable` State values that are not in the list of supported Composer stability values can be expressed as build metadata: .. code-block:: json :caption: composer.json using build metadata for custom state labels { "name": "vendor/example", "type": "typo3-cms-extension", "description": "Example extension", "extra": { "typo3/cms": { "extension-key": "example_extension", "version": "1.0.0+obsolete", "Package": { "providesPackages": {} } } } } In this example, `obsolete` is preserved as build metadata and can still be displayed in the TYPO3 Extension Manager. The former `state = excludeFromUpdates` value should now be expressed via a dedicated boolean flag: .. code-block:: json :caption: composer.json marking an extension as excluded from updates { "name": "vendor/example", "type": "typo3-cms-extension", "description": "Example extension", "extra": { "typo3/cms": { "extension-key": "example_extension", "version": "1.0.0", "exclude-from-updates": true, "Package": { "providesPackages": {} } } } } PHP constraints --------------- If an extension declares a PHP version dependency, it should be in the `require` section of :file:`composer.json`: .. code-block:: json :caption: composer.json defining a PHP version constraint { "name": "vendor/example", "version": "1.0.0", "type": "typo3-cms-extension", "description": "Example extension", "require": { "typo3/cms-core": "^14.2", "php": "^8.2" }, "extra": { "typo3/cms": { "extension-key": "example_extension", "Package": { "providesPackages": {} } } } } The PHP dependency remains relevant for metadata and compatibility checks in TYPO3 classic mode, but it is not used for extension dependency ordering. If an extension provides regular Composer packages itself in TYPO3 classic mode, these packages must be declared in `extra.typo3/cms.Package.providesPackages`. Packages that are already shipped by TYPO3 or already provided by another loaded extension do not need to be repeated there. Entries in `providesPackages` may also associate a provided package with a relative path to a Composer vendor directory inside the extension. If that directory contains a Composer-generated `autoload.php`, TYPO3 includes it early during bootstrap. If an extension does not provide any regular Composer packages itself, `providesPackages` must still be present and set to an empty object to avoid deprecation messages and to declare future compatibility with TYPO3 classic mode. If strict :file:`composer.json` validation is required and the extension is published to Packagist where setting the top level `version` field is not recommended, it is recommended to set the version via `extra.typo3/cms.version`. If the `version` field is set anyway, it is recommended to omit `extra.typo3/cms.version` to avoid redundant data points. Impact ====== There is no impact on Composer-based TYPO3 installations. TYPO3 classic installations will trigger a deprecation message for extensions that ship a :file:`ext_emconf.php` and have not defined the required metadata in :file:`composer.json`. Affected installations ====================== TYPO3 classic installations are affected if they use extensions that: * still ship :file:`ext_emconf.php` * do not define a `"version"` field or `extra.typo3/cms.version` * or do not define `extra.typo3/cms.Package.providesPackages` at all, even as an empty object Migration ========= Extension authors should move extension metadata from :file:`ext_emconf.php` to :file:`composer.json`. This includes: * the extension version via `"version"` or `extra.typo3/cms.version` * `providesPackages` via `extra.typo3/cms.Package.providesPackages`, using it for packages provided by the extension itself; packages already shipped by TYPO3 or already provided by another extension do not need to be repeated * optional autoload paths for self-provided Composer packages via `extra.typo3/cms.Package.providesPackages`, pointing to a Composer vendor directory whose `autoload.php` can be included early * supported stability via version suffixes such as `-dev`, `-alpha1`, `-beta2`, or `-RC3` * custom former state labels via build metadata such as `+obsolete` * update exclusion via `extra.typo3/cms.exclude-from-updates` * PHP constraints via the :file:`require.php` entry For the time being, :file:`ext_emconf.php` may still need to be kept for third-party tooling such as TYPO3 TER or Tailor. However, once the required metadata is correctly defined in :file:`composer.json`, TYPO3 will no longer evaluate :file:`ext_emconf.php`. .. index:: ext:core, NotScanned