TYPO3 v15 dev-main snapshot ()

This commit is contained in:
2026-08-10 22:31:09 +02:00
commit af8cc155b5
6818 changed files with 642608 additions and 0 deletions
@@ -0,0 +1,47 @@
.. include:: /Includes.rst.txt
.. _deprecation-97536-1651523804:
=======================================
Deprecation: #97536 - LinkResultFactory
=======================================
See :issue:`97536`
Description
===========
The PHP class :php:`TYPO3\CMS\Frontend\Typolink\LinkResultFactory` has been
marked as deprecated, as its functionality has been migrated into
:php:`TYPO3\CMS\Frontend\Typolink\LinkFactory`.
In addition, the method :php:`createFromUriString()` has been marked as
deprecated as the shortened variant `createUri()` should be used instead.
Impact
======
Instantiating an object of type :php:`LinkResultFactory` will instantiate
:php:`LinkFactory` instead via class alias in TYPO3 v12, as the class itself
has been removed.
Calling :php:`createFromUriString()` will trigger a deprecation log entry.
The extension scanner reports affected extensions.
Affected installations
======================
TYPO3 installations with custom extensions instantiating :php:`LinkResultFactory`
as a PHP object or calling :php:`createFromUriString()` directly, which is very
rare.
Migration
=========
TYPO3 extensions should migrate to using :php:`LinkFactory` and its main methods
directly.
.. index:: Frontend, PHP-API, FullyScanned, ext:frontend
@@ -0,0 +1,66 @@
.. include:: /Includes.rst.txt
.. _deprecation-98613:
===================================================================
Deprecation: #98613 - CKEditor removePlugin configuration as string
===================================================================
See :issue:`98613`
Description
===========
The :yaml:`removePlugins` option needs to be assigned as an array in CKEditor 5.
While we recommended passing the option already as an array, CKEditor 4 needed a
comma-separated string.
The conversion was only handled if the integrator passed an array, which means
if someone already provided a comma-separated string the option was simply
passed as-is to the editor configuration.
To avoid JavaScript errors, we are going to migrate it to array for now. The
possibility to pass the option as a string is deprecated and will be removed
with TYPO3 v13.
Impact
======
Passing the CKEditor configuration :yaml:`removePlugins` as string will trigger
a PHP :php:`E_USER_DEPRECATED` error.
Affected installations
======================
All installations that pass the CKEditor configuration :yaml:`removePlugins` as
string.
Migration
=========
Adjust your CKEditor configuration and pass :yaml:`removePlugins` as array.
Before
------
.. code-block:: yaml
editor:
config:
removePlugins: image
After
-----
.. code-block:: yaml
editor:
config:
removePlugins:
- image
.. index:: RTE, NotScanned, ext:rte_ckeditor
@@ -0,0 +1,102 @@
.. include:: /Includes.rst.txt
.. _deprecation-98996-1667549770:
=================================================================================================
Deprecation: #98996 - Doctrine DBAL: BackendWorkspaceRestriction and FrontendWorkspaceRestriction
=================================================================================================
See :issue:`98996`
Description
===========
TYPO3's Database Abstraction Layer works with restrictions to limit the selection
based on TYPO3's TCA information for certain database tables.
With the introduction of Doctrine DBAL and the Database Restrictions in TYPO3 v8,
the two restrictions
:php:`\TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction`
and :php:`\TYPO3\CMS\Core\Database\Query\Restriction\FrontendWorkspaceRestriction`
were introduced, which had some conceptual flaws. The usages to these restrictions
were removed subsequently within TYPO3 Core since TYPO3 v9, as various improvements
were made to the database layer when working with Workspaces.
In TYPO3 v9.5.x a new restriction :php:`\TYPO3\CMS\Core\Database\Query\Restriction\WorkspaceRestriction`
:ref:`was added <important-84985>`, which superseded both existing
Workspace-related restrictions, solving almost all cases needed when reading
rows from the database.
The former restriction classes have now been marked as deprecated.
Impact
======
Instantiating any of the classes
* :php:`\TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction`
* :php:`\TYPO3\CMS\Core\Database\Query\Restriction\FrontendWorkspaceRestriction`
will trigger a PHP deprecation notice.
Affected installations
======================
TYPO3 installations with custom extensions explicitly using one of the
restrictions. Affected extensions can be detected via the Extension Scanner
in the Install Tool / Maintenance Area.
Migration
=========
Use the class :php:`\TYPO3\CMS\Core\Database\Query\Restriction\WorkspaceRestriction`
instead. It allows to hand in the current workspace ID, which then fetches all
records from the database only for a certain workspace (unlike
:php:`FrontendWorkspaceRestriction` which did not limit the database query to
one workspace in certain cases).
When querying the database, ensure to use the Overlay APIs in
:php:`\TYPO3\CMS\Core\Domain\Repository\PageRepository->versionOL` (Frontend)
or :php:`\TYPO3\CMS\Backend\Utility\BackendUtility::workspaceOL()` would then
filter the invalid records.
Example
-------
This shows a regular example within the TYPO3 backend to query records
within
.. code-block:: php
$context = GeneralUtility::makeInstance(Context::class);
$workspaceId = $context->getPropertyFromAspect('workspace', 'id', 0);
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('tt_content');
$queryBuilder->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class))
->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, $workspaceId));
$statement = $queryBuilder
->select('*')
->from('tt_content')
->where(
$queryBuilder->expr()->eq('colPos', $queryBuilder->createNamedParameter(0))
)
->execute();
$records = [];
while ($record = $statement->fetchAssociative()) {
BackendUtility::workspaceOL('tt_content', $record, $workspaceId);
if (is_array($record)) {
$records[] = $record;
}
}
return $records;
.. index:: Database, FullyScanned, ext:core
@@ -0,0 +1,44 @@
.. include:: /Includes.rst.txt
.. _deprecation-99019-1667905697:
================================================================
Deprecation: #99019 - Deprecated ext_emconf.php clearCacheOnLoad
================================================================
See :issue:`99019`
Description
===========
The array keys :php:`clearCacheOnLoad` and :php:`clearcacheonload`
in extension's :file:`ext_emconf.php` files have been deprecated and
can be removed.
When loading or unloading extensions using the extension manager,
all caches are always cleared.
Impact
======
When loading or unloading extensions using the extension manager, all
caches are flushed, regardless of the boolean toggle in :file:`ext_emconf.php`.
Affected installations
======================
Instances with extensions :file:`ext_emconf.php` files setting :php:`clearCacheOnLoad`
or :php:`clearcacheonload`.
Migration
=========
Simply drop this key from :file:`ext_emconf.php`. Extensions with this toggle set
to true that want to keep compatibility with both TYPO3 v11 and v12 should keep
the setting until v11 compatibility is dropped from the extensions.
.. index:: PHP-API, NotScanned, ext:extensionmanager
@@ -0,0 +1,49 @@
.. include:: /Includes.rst.txt
.. _deprecation-99020-1667911024:
==========================================================
Deprecation: #99020 - Deprecate TypoScript/TemplateService
==========================================================
See :issue:`99020`
Description
===========
The class :php:`TYPO3\CMS\Core\TypoScript\TemplateService` has been marked as deprecated
in TYPO3 v12 and will be removed in v13. This class is sometimes indirectly accessed
using :php:`TypoScriptFrontendController->tmpl` or :php:`$GLOBALS['TSFE']->tmpl`.
Impact
======
The class :php:`TemplateService` is part of the old TypoScript parser and has been
substituted with a :ref:`new parser approach <breaking-97816-1664800747>`.
Actively calling class methods will trigger a deprecation log level warning.
Affected installations
======================
Instances with extensions directly using :php:`TemplateService` or indirectly
using it by calling :php:`TypoScriptFrontendController->tmpl` or
:php:`$GLOBALS['TSFE']->tmpl` are affected.
Migration
=========
The class :php:`TemplateService` is typically called in TYPO3 frontend scope. Extensions
should avoid using :php:`TypoScriptFrontendController->tmpl` and :php:`$GLOBALS['TSFE']->tmpl`
methods and properties. They can retrieve TypoScript from the PSR-7 request instead
using the attribute :ref:`frontend.typoscript <feature-98914-1666689687>`.
As example, the full frontend TypoScript can be retrieved like this:
.. code-block:: php
$fullTypoScript = $request->getAttribute('frontend.typoscript')->getSetupArray();
.. index:: PHP-API, FullyScanned, ext:core
@@ -0,0 +1,46 @@
.. include:: /Includes.rst.txt
.. _deprecation-99031-1667998430:
=================================================================
Deprecation: #99031 - Deprecated f:format.html in Backend context
=================================================================
See :issue:`99031`
Description
===========
The :html:`<f:format.html />` ViewHelper :php:`TYPO3\CMS\Fluid\ViewHelpers\Format\HtmlViewHelper`
should not be used in TYPO3 backend context anymore.
Using this ViewHelper in backend context triggers frontend :typoscript:`parseFunc` logic, which
should be avoided in the backend.
There are other ViewHelpers to output and parse HTML in backend context. See description of
the :ref:`f:sanitize.html <feature-94825-1667998632>` ViewHelper for more details.
Impact
======
Using :html:`<f:format.html />` logs a deprecation level warning.
Affected installations
======================
Instances with extensions that come with backend modules using Fluid rendering and
accessing :html:`<f:format.html />` are affected.
Migration
=========
Switch to one of the other ViewHelpers instead, typically :html:`<f:sanitize.html />`
to secure a given HTML string, :html:`<f:transform.html />` to parse links in HTML,
or :html:`<f:format.raw />` to output the HTML as is when the input can be considered
"secure".
.. index:: Backend, Fluid, NotScanned, ext:fluid
@@ -0,0 +1,93 @@
.. include:: /Includes.rst.txt
.. _deprecation-99040-1668076207:
==============================================================================
Deprecation: #99040 - Deprecated TypoScript setup "constants" top-level-object
==============================================================================
See :issue:`99040`
Description
===========
The frontend TypoScript setup (!) top-level-object :typoscript:`constants` can be
used to define constants for replacement inside a :typoscript:`parseFunc`.
If :typoscript:`parseFunc` somewhere is configured with :typoscript:`.constants = 1`,
then all occurrences of the constant in the text will be substituted with the
actual value.
This construct has been marked as deprecated in TYPO3 v12 and will be removed with v13.
Impact
======
Using the :typoscript:`constants` top-level-object in combination with the
:typoscript:`constants = 1` in :typoscript:`parseFunc` to substitute strings
like :typoscript:`###MY_CONSTANT###` triggers a deprecation level log error
in TYPO3 v12 and will stop working in v13.
Affected installations
======================
This is a relatively rarely used feature, not well-known by many integrators.
TYPO3 integrators should watch out for :typoscript:`###` markers within
TypoScript, the :guilabel:`Template` backend module search functionality should
help here.
The :guilabel:`Template Analyzer` will also show usages of the setup top-level-object
:typoscript:`constants`.
Migration
=========
One possible solution is to switch to TypoScript constants / settings instead
for simple cases.
A simple example usage before:
.. code-block:: typoscript
TypoScript setup:
constants.EMAIL = mail@example.com
page = PAGE
page.10 = TEXT
page.10.value = Write an email to ###EMAIL###
page.10.parseFunc.constants = 1
Switching to a TypoScript constant / setting:
.. code-block:: typoscript
TypoScript constants / settings:
myEmail = mail@example.com
TypoScript setup:
page = PAGE
page.10 = TEXT
page.10.value = Write an email to {$myEmail}
The main usage of this feature has been a "magic" substitution within :typoscript:`lib.parseFunc_RTE`:
When :sql:`tt_content` rich text content elements contain such substitution strings, they are
replaced by :typoscript:`parseFunc` accordingly. For instance, a tt_content RTE element with the
content `Send an email to ###EMAIL###` would substitute to `Send an email to email@example.com` *if*
the top-level setup :typoscript:`constants` object has been set up. This substitution
relies on the fact that editors actively know about and use this construct: If only one content
element did not prepare for this - since an editor forgot or hasn't been trained about it, changing
such a constant on TypoScript level would still lead to faulty frontend output, rendering the
entire substitution approach useless.
In case instances still rely on this magic substitution principle, and made sure all editors
always know and follow this approach, instances can use the :typoscript:`userFunc`
property of :typoscript:`parseFunc` to re-implement the functionality: basically by
copying the deprecated code to an own class and registering the :typoscript:`userFunc`
in :typoscript:`lib.parseFunc_RTE`.
.. index:: TypoScript, NotScanned, ext:frontend
@@ -0,0 +1,72 @@
.. include:: /Includes.rst.txt
.. _deprecation-99050-1668086497:
=========================================================================
Deprecation: #99050 - TypoScript _CSS_PAGE_STYLE and config.removePageCss
=========================================================================
See :issue:`99050`
Description
===========
Integrators can use the TypoScript setup plugin-level property :typoscript:`_CSS_PAGE_STYLE`
to define custom CSS that is loaded in the frontend. To suppress this output, the additional
property :typoscript:`config.removePageCss` (or :typoscript:`somePageObject.config.removePageCss`)
can be used.
Handling of both plugin-level :typoscript:`_CSS_PAGE_STYLE` and config object level
property :typoscript:`removePageCss` have been marked as deprecated in TYPO3 v12 and
will be removed in v13.
Impact
======
Using a TypoScript property like :typoscript:`plugin.tx_myPlugin._CSS_PAGE_STYLE` or
the config property :typoscript:`removePageCss` in :typoscript:`config.removePageCss`
or in a page-specific usage like :typoscript:`myPage.config.removePageCss` triggers
a deprecation level log entry.
Affected installations
======================
TypoScript property :typoscript:`_CSS_PAGE_STYLE` is a relatively rarely used
property in TYPO3 instances. Instances can use the :guilabel:`Template` backend
module to scan for usages.
Migration
=========
Integrators should avoid using :typoscript:`_CSS_PAGE_STYLE` on plugin level. They
should switch adding CSS on a :typoscript:`PAGE` level. A direct replacement looks
like this:
Before:
.. code-block:: typoscript
plugin.tx_myPlugin._CSS_PAGE_STYLE (
.myClass { text-align: center }
)
After:
.. code-block:: typoscript
page.cssInline {
10 = TEXT
10.value (
.myClass { text-align: center }
)
}
As a general note, the :typoscript:`PAGE` property :typoscript:`includeCSS` is often
better suited to include CSS as files, especially when frontend CSS is generated by
some processor like SCSS.
.. index:: TypoScript, NotScanned, ext:frontend
@@ -0,0 +1,67 @@
.. include:: /Includes.rst.txt
.. _deprecation-99075-1668337874:
=====================================================
Deprecation: #99075 - fe_users and fe_groups TSconfig
=====================================================
See :issue:`99075`
Description
===========
The two database fields :sql:`fe_users.TSconfig` and :sql:`fe_groups.TSconfig`
have been marked as deprecated in TYPO3 v12 and will be removed in v13 along with
its PHP API.
Impact
======
Backend users and groups provide these :guilabel:`TSconfig` fields as well, they are the base
of the well-known `UserTsConfig` configuration to specify rendering and behavior of
TYPO3 backend-related details. This is kept.
Frontend users and groups had these fields as well, they are unused by TYPO3 core
and only a few extensions ever used them.
The frontend user and group related database fields, the editing functionality of
these fields in the backend (TCA), and according PHP API will be removed with
TYPO3 v13. In detail:
* Database field :sql:`fe_users.TSconfig` will be removed from the table definition.
* Database field :sql:`fe_groups.TSconfig` will be removed from the table definition.
* Rendering and editing setup of field :php:`fe_users.TSconfig` will be removed from TCA.
* Rendering and editing setup of field :php:`fe_groups.TSconfig` will be removed from TCA.
* Default configuration value :php:`$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultUserTSconfig']`
will be removed.
* PHP method :php:`\TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication->getUserTSconf()`
will be removed.
Affected installations
======================
Instances are relatively unlikely to be affected: Only a few extensions ever used these
fields to store configuration for frontend users, most likely extensions related to
additional authentication mechanisms.
The extension scanner will find extensions that access :php:`$GLOBALS['TYPO3_CONF_VARS']['FE']['defaultUserTSconfig']`
or call :php:`\TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication->getUserTSconf()` as "weak" matches.
Migration
=========
Extensions should avoid using the fields to store and access configuration in a
TypoScript-like syntax. Affected extensions should add own fields prefixed with an
extension-specific key, or switch to a file-based configuration approach, if possible.
To simulate the deprecated logic, extensions may extract the deprecated parsing logic from
:php:`FrontendUserAuthentication` class into an own service, probably by fetching group data
using :php:`\TYPO3\CMS\Core\Authentication\GroupResolver`, and then merge and parse group
data of the field with frontend user-specific data.
.. index:: Database, Frontend, LocalConfiguration, PHP-API, TCA, TSConfig, TypoScript, PartiallyScanned, ext:frontend
@@ -0,0 +1,64 @@
.. include:: /Includes.rst.txt
.. _deprecation-99084-1667981931:
===============================================================
Deprecation: #99084 - Make trigger of context menu configurable
===============================================================
See :issue:`99084`
Description
===========
The context menu JavaScript API was adapted to also support opening
the menu through the "contextmenu" event type (right click) only.
The configuration for the context menu was streamlined and now reflects
its purpose. The trigger can now be set to "click" or "contextmenu".
Impact
======
Using the deprecated JavaScript API will trigger a warning in the console.
Affected installations
======================
All extensions that use the context menu.
Migration
=========
Replace the trigger :html:`class="t3js-contextmenutrigger"` with
:html:`data-contextmenu-trigger="click"`. Prefix all configuration with
:html:`data-contextmenu-`.
Before
------
.. code-block:: html
<a href="#"
class="t3js-contextmenutrigger"
data-table="pages"
data-uid="10"
data-context="tree"
>...</a>
After
-----
.. code-block:: html
<a href="#"
data-contextmenu-trigger="click"
data-contextmenu-table="pages"
data-contextmenu-uid="10"
data-contextmenu-context="tree"
>...</a>
.. index:: Backend, JavaScript, NotScanned
@@ -0,0 +1,140 @@
.. include:: /Includes.rst.txt
.. _deprecation-99098-1668546853:
===========================================================
Deprecation: #99098 - Static usage of FormProtectionFactory
===========================================================
See :issue:`99098`
Description
===========
:php:`\TYPO3\CMS\Core\FormProtection\FormProtectionFactory` has been
constructed in a static class manner in TYPO3 v6.2, using a static property
based instance cache to avoid recreating instances for a specific typed
FormProtection implementation. This design made it impossible to retrieve an
instance of this class via dependency injection. Another side-effect was that
ensuring a properly cleared state between tests has been hard and often
spread to other tests and thus influencing them.
To mitigate these issues, :php:`\TYPO3\CMS\Core\FormProtection\FormProtectionFactory`
is now transformed to a non-static class usage with injected services
and the Core runtime cache, removing the static property cache.
Based on these changes, the old static methods :php:`get()` and
:php:`purgeInstances()` are now deprecated.
There are two general ways to get a specific FormProtection implementation:
* auto-detected from request: :php:`$formProtectionFactory->createFromRequest()`
* create for a specific type: :php:`$formProtectionFactory->createForType()`
Possible types for :php:`$formProtectionFactory->createForType()` are `frontend`
`backend`, `installtool` or `disabled`.
Impact
======
Using any of the following class methods
* :php:`\TYPO3\CMS\Core\FormProtection\FormProtectionFactory::get()`
* :php:`\TYPO3\CMS\Core\FormProtection\FormProtectionFactory::purgeInstances()`
will trigger a PHP deprecation notice and will throw a fatal PHP error in
TYPO3 v13.
Affected installations
======================
The extension scanner will find extensions calling :php:`FormProtectionFactory::get()`
or :php:`FormProtectionFactory::purgeInstances()` as "strong" matches.
Migration
=========
Provided implementation by TYPO3 core
-------------------------------------
Before
.. code-block:: php
// use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
// BackendFormProtection
$formProtection = FormProtectionFactory::get(BackendFormProtection::class);
$formProtection = FormProtectionFactory::get('backend');
// FrontendFormProtection
$formProtection = FormProtectionFactory::get(FrontedFormProtection::class);
$formProtection = FormProtectionFactory::get('frontend');
// Default / Disabled FormProtection
$formProtection = FormProtectionFactory::get(DisabledFormProtection::class);
$formProtection = FormProtectionFactory::get('default');
After
It is recommended to use :php:`FormProtectionFactory->createForRequest()` to
auto-detect which type is needed and return the corresponding instance:
.. code-block:: php
// use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
// Better: Get FormProtectionFactory injected by DI.
$formProtectionFactory = GeneralUtility::makeInstance(FormProtectionFactory::class);
// $request is assumed to be available, for instance in controller classes.
$formProtection = $formProtectionFactory->createFromRequest($request);
To create a specific type directly, using following replacements:
.. code-block:: php
// use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
// Better: Get FormProtectionFactory injected by DI.
$formProtectionFactory = GeneralUtility::makeInstance(FormProtectionFactory::class);
// BackendFormProtection
$formProtection = $formProtectionFactory->createFromType('backend');
// FrontendFormProtection
$formProtection = $formProtectionFactory->createFromType('frontend');
// Default / Disabled FormProtection
$formProtection = $formProtectionFactory->createFromType('disabled');
Custom FormProtection-based implementation
------------------------------------------
Before
.. code-block:: php
// use TYPO3\CMS\Core\FormProtection\FormProtectionFactory;
$formProtection = FormProtectionFactory::get(
Vendor\ExtensionKey\FormProtection\CustomFormProtection::class,
$customService,
'someDirectValue',
...
);
After
.. code-block:: php
// Create an instance of the class yourself, take care of an
// instance cache if needed.
GeneralUtility::makeInstance(
Vendor\ExtensionKey\FormProtection\CustomFormProtection::class,
$constructorArguments
);
.. index:: PHP-API, FullyScanned, ext:core
@@ -0,0 +1,51 @@
.. include:: /Includes.rst.txt
.. _deprecation-99150-1669026092:
============================================================
Deprecation: #99150 - Updated chart library in EXT:dashboard
============================================================
See :issue:`99150`
Description
===========
The library `chart.js` used to render charts in a dashboard has been
updated to version 4.x, introducing some breaking changes. A migration layer is
in place to migrate known and used affected settings.
Impact
======
The CSS file :file:`EXT:dashboard/Resources/Public/Css/Contrib/chart.css` became
obsolete with the update of `chart.js` and was therefore removed without
replacement.
If a migration is executed, an entry will be written into the deprecation log.
Affected installations
======================
All plugins providing third-party chart widgets are affected.
Migration
=========
Migrate the configuration as mentioned in the table below.
================================ ============================
Old setting New setting
================================ ============================
graphConfig/options/scales/xAxes graphConfig/options/scales/x
graphConfig/options/scales/yAxes graphConfig/options/scales/y
================================ ============================
Also, please consult the migration guides available at
* https://www.chartjs.org/docs/latest/migration/v3-migration.html
* https://www.chartjs.org/docs/latest/migration/v4-migration.html
.. index:: Backend, JavaScript, NotScanned, ext:dashboard
@@ -0,0 +1,82 @@
.. include:: /Includes.rst.txt
.. _deprecation-99170-1669411707:
=================================================================
Deprecation: #99170 - config.baseURL and <base> tag functionality
=================================================================
See :issue:`99170`
Description
===========
The TypoScript option :typoscript:`config.baseURL` has been deprecated.
The option allowed to set a fixed URL which was then added as :html:`<base>` tag
to the HTML :html:`<head>` part of a website. This feature was particularly
useful back in previous TYPO3 versions in combination with RealURL for
providing absolute links.
However, TYPO3 v9 introduced site handling, which produces absolute
URLs or absolute paths directly. In addition, with TYPO3 v12.1 the option
:ref:`config.forceAbsoluteUrls = 1 <feature-87919-1667984808>` allows to
generate absolute URLs completely for all links, images or assets, making the
baseURL option obsolete, as it isn't as powerful as the mentioned alternatives:
It only allows to define a static value rather than loading the information
based on the current request. With the TypoScript setting this is only possible
with having multiple variants of :typoscript:`config.baseURL` set via TypoScript
conditions.
In addition to the TypoScript option, the related public PHP methods are now
obsolete and have also been deprecated:
* :php:`\TYPO3\CMS\Core\Page\PageRenderer->setBaseUrl()`
* :php:`\TYPO3\CMS\Core\Page\PageRenderer->getBaseUrl()`
* :php:`\TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->baseUrlWrap()`
Impact
======
Setting the TypoScript option :typoscript:`config.baseURL` will trigger a
deprecation message, but will continue to work in TYPO3 v12.
Calling any of the PHP methods directly in PHP code will also trigger a
deprecation message.
Affected installations
======================
TYPO3 installations using the :typoscript:`config.baseURL` option, which is
common for projects which were started before TYPO3 v9.
Migration
=========
Use the site configuration with fully-qualified domain names to achieve the same
result, as rendering a :html:`<base>` tag in HTML will not be supported
out-of-the-box anymore by TYPO3 v13.
If you are already using the site configuration, but need to build
fully-qualified URLs, you can safely remove the TypoScript option
:typoscript:`config.baseURL` without any impact in 99% of the use cases.
In special cases the option :typoscript:`config.forceAbsoluteUrls = 1` can
help you to achieve the same result.
If you need to manually set a :html:`<base>` tag, this is still possible via
TypoScript:
.. code-block:: typoscript
page = PAGE
page.headTag.append = TEXT
page.headTag.append.value = <base href="https://static.example.com/">
In general, it is recommended not to use the :html:`<base>` tag, as
certain crawlers cannot interpret this HTML tag properly.
.. index:: TypoScript, FullyScanned, ext:frontend
@@ -0,0 +1,50 @@
.. include:: /Includes.rst.txt
.. _deprecation-99201-1669561044:
===========================================================================
Deprecation: #99201 - UserSessionManager->createFromGlobalCookieOrAnonymous
===========================================================================
See :issue:`99201`
Description
===========
The PHP method :php:`\TYPO3\CMS\Core\Session\UserSessionManager->createFromGlobalCookieOrAnonymous`
has been deprecated. It served as a low-level API to create a user session based
on the superglobal :php:`$_COOKIE` variable. However, the usage of PHP
superglobals should be avoided in TYPO3 code. As TYPO3 Core is moving towards
accessing request information via PSR-7 request attribute, this method is also
deprecated, even though it was only introduced in TYPO3 v11.0.
Impact
======
Calling the method directly within PHP code of a third-party extension will
trigger a PHP deprecation message.
Affected installations
======================
The method was only introduced in TYPO3 v11.0, and only acted as a
backwards-compatibility layer for using the UserSessionManager API class in
legacy code, which is why it is very unlikely that this method is called directly
in any TYPO3 extension. However, the Extension Scanner will pick up any
usages of this method.
TYPO3 extensions usually do not use the :php:`UserSessionManager` directly to create
a user session.
Migration
=========
The :php:`UserSessionManager` API also provides the
:php:`createFromRequestOrAnonymous(ServerRequestInterface $request)` method when
the API itself was added. The method achieves the same logic based on a PSR-7
request. Use this method instead and use PSR-7 as much as possible.
.. index:: PHP-API, FullyScanned, ext:core
@@ -0,0 +1,38 @@
.. include:: /Includes.rst.txt
.. _feature-100586-1681464016:
==============================================================
Feature: #100586 - Null-safe operator in TypoScript conditions
==============================================================
See :issue:`100586`
Description
===========
By raising TYPO3's Symfony dependencies to `6.2` in :issue:`99239`, a couple
of new features were made available for the `expression language`_, which is
used by TYPO3 for its :ref:`TypoScript conditions <t3tsref:conditions>`.
One of those new features is the `null-safe operator`_. This operator is
especially useful when accessing properties on objects, which however might
not be available in some context, e.g. "TSFE" in the backend.
TYPO3 designed its custom expression functions in a way that they support the
usage of the null-safe operator by default. This is done by returning
:php:`NULL` in case the requested object is not available.
Therefore, instead of :typoscript:`[getTSFE() && getTSFE().id == 123]`,
integrators can simplify the condition to :typoscript:`[getTSFE()?.id == 123]`.
Impact
======
It's now possible to simplify TypoScript conditions using the new expression
language features, especially the null-safe operator.
.. _expression language: https://symfony.com/doc/current/reference/formats/expression_language.html
.. _null-safe operator: https://symfony.com/doc/current/reference/formats/expression_language.html#null-safe-operator
.. index:: Backend, Frontend, TypoScript, ext:core
@@ -0,0 +1,27 @@
.. include:: /Includes.rst.txt
.. _feature-87919-1667984808:
==============================================================
Feature: #87919 - Allow generation of absolute URLs completely
==============================================================
See :issue:`87919`
Description
===========
A new TypoScript option :typoscript:`config.forceAbsoluteUrls = 1` has been added.
Impact
======
If the option is set, all links, references to images or assets previously built with a relative
or absolute path (e.g. :file:`/fileadmin/my-pdf.pdf`) will be rendered as absolute URLs
with the site prefix / current domain.
Examples for such use cases are the generation of a full static version of a TYPO3 site
for sending a page via email.
.. index:: TypoScript, ext:frontend
@@ -0,0 +1,94 @@
.. include:: /Includes.rst.txt
.. _feature-91499:
==============================================================================================
Feature: #91499 - Additional attributes for includeJS, includeCSS and all other page.include**
==============================================================================================
See :issue:`91499`
Description
===========
The :php:`PageRenderer` supports additional tag attributes for CSS and JavaScript files.
These data attributes can be configured using a key/value list via TypoScript.
* :typoscript:`page.includeCSS`
* :typoscript:`page.includeCSSLibs`
* :typoscript:`page.includeJS`
* :typoscript:`page.includeJSFooter`
* :typoscript:`page.includeJSLibs`
* :typoscript:`page.includeJSFooterlibs`
Impact
======
It is now possible to extend :html:`<script>` and :html:`<link>` tags with any
kind of HTML tag attributes, which is very useful for integration with
external scripts such as a consent manager.
Example
-------
Configuration:
.. code-block:: typoscript
page = PAGE
page {
includeCSSLibs {
someIncludeFile = fileadmin/someIncludeFile1
someIncludeFile.data-foo = includeCSSLibs
}
includeCSS {
someIncludeFile = fileadmin/someIncludeFile2
someIncludeFile.data-foo = includeCSS
}
includeJSLibs {
someIncludeFile = fileadmin/someIncludeFile3
someIncludeFile.data-consent-type = marketing
}
includeJS {
someIncludeFile = fileadmin/someIncludeFile4
someIncludeFile.data-consent-type = essential
}
includeJSFooterlibs {
someIncludeFile = fileadmin/someIncludeFile5
someIncludeFile.data-my-attribute = foo
}
includeJSFooter {
someIncludeFile = fileadmin/someIncludeFile6
someIncludeFile.data-foo = includeJSFooter
}
}
Reserved keywords which will not be mapped to attributes are:
- :typoscript:`compress`
- :typoscript:`forceOnTop`
- :typoscript:`allWrap`
- :typoscript:`type` (set automatically, depending on :typoscript:`config.doctype`)
- :typoscript:`disableCompression`
- :typoscript:`excludeFromConcatenation`
- :typoscript:`external`
- :typoscript:`inline`
Resulting HTML of the above example:
.. code-block:: html
<head>
<link rel="stylesheet" type="text/css" href="/typo3conf/ext/myext/Resources/Public/someIncludeFile1" media="all" data-foo="includeCSS">
<link rel="stylesheet" type="text/css" href="/typo3conf/ext/myext/Resources/Public/someIncludeFile2" media="all" data-foo="includeCSSLibs">
<script src="/typo3conf/ext/myext/Resources/Public/someIncludeFile3" data-consent-type="marketing"></script>
<script src="/typo3conf/ext/myext/Resources/Public/someIncludeFile4" data-consent-type="essential"></script>
</head>
<body>
<script src="/typo3conf/ext/myext/Resources/Public/someIncludeFile5" data-my-attribute="foo"></script>
<script src="/typo3conf/ext/myext/Resources/Public/someIncludeFile6" data-foo="includeJSFooteribs"></script>
</body>
.. index:: Frontend, TypoScript, ext:frontend
@@ -0,0 +1,34 @@
.. include:: /Includes.rst.txt
.. _feature-93112-1667904722:
=====================================================
Feature: #93112 - Allow glob patterns in yaml imports
=====================================================
See :issue:`93112`
Description
===========
The TYPO3 :php:`YamlFileLoader` (used, for example, when loading site configurations) does
now support importing files with glob patterns. This will simplify the configuration
and allow for more compact configuration files.
To enable globbing, set the option :yaml:`glob: true` on the import level.
Impact
======
You can now use `glob()` syntax when importing configuration files in YAML.
Example:
.. code-block:: yaml
imports:
- { resource: "./**/*.yaml", glob: true }
- { resource: "EXT:core/Tests/**/Configuration/**/SiteConfigs/*.yaml", glob: true }
.. index:: PHP-API, YAML, ext:core
@@ -0,0 +1,27 @@
.. include:: /Includes.rst.txt
.. _feature-93423-1667988850:
==========================================================================
Feature: #93423 - Show warning about duplicated root pages in sites module
==========================================================================
See :issue:`93423`
Description
===========
It might happen that the same root page ID is configured for multiple site
configurations, e.g. in case corresponding files were copied manually. This
might lead to misbehavior, since always the last site with this root page
ID defined is used by TYPO3. As such configuration errors might be hard to
spot, the :guilabel:`Sites` module now informs about such duplications in
the site configuration overview view.
Impact
======
The site module now warns administrators in case the same root page ID is used
in multiple site configurations.
.. index:: Backend, ext:backend
@@ -0,0 +1,91 @@
.. include:: /Includes.rst.txt
.. _feature-96005-1660340104:
===============================================================
Feature: #96005 - Allow tagging and aliasing of data processors
===============================================================
See :issue:`96005`
Description
===========
It is now possible to set an alias / identifier for data processors by
tagging them with the :yaml:`data.processor` tag in the
:file:`Configuration/Services.yaml` file and defining the :yaml:`identifier`
key. On the one hand, this improves readability in corresponding TypoScript
configurations, since those aliases / identifiers can be used instead of
the fully-qualified class name, while also providing dependency injection out
of the box. On the other hand, this allows improving and enhancing the
functionality of data processors in the future by automatically adding
tagged processors to a registry.
Tagging a data processor in the :file:`Configuration/Services.yaml` file:
.. code-block:: yaml
Vendor\MyExt\DataProcessing\AwesomeProcessor:
tags:
- { name: 'data.processor', identifier: 'awesome' }
Usage in TypoScript:
.. code-block:: typoscript
dataProcessing.10 = awesome
All data processors shipped by TYPO3 are already tagged and can therefore
be used with their alias / identifier in your TypoScript configuration:
.. code-block:: typoscript
# Default with fully-qualified class name (still supported):
dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\CommaSeparatedValueProcessor
20 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
30 = TYPO3\CMS\Frontend\DataProcessing\FilesProcessor
40 = TYPO3\CMS\Frontend\DataProcessing\FlexFormProcessor
50 = TYPO3\CMS\Frontend\DataProcessing\GalleryProcessor
60 = TYPO3\CMS\Frontend\DataProcessing\LanguageMenuProcessor
70 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
80 = TYPO3\CMS\Frontend\DataProcessing\SiteProcessor
90 = TYPO3\CMS\Frontend\DataProcessing\SiteLanguageProcessor
100 = TYPO3\CMS\Frontend\DataProcessing\SplitProcessor
}
# New alternative using the alias / identifier:
dataProcessing {
10 = comma-separated-value
20 = database-query
30 = files
40 = flex-form
50 = gallery
60 = language-menu
70 = menu
80 = site
90 = site-language
100 = split
}
.. note::
The standard service aliasing mechanism is still supported. However,
it is recommended to tag the data processors instead, because this will
automatically add them to the internal :php:`DataProcessorRegistry`,
enabling dependency injection by default. Otherwise the service would need
to be set :yaml:`public`.
.. note::
It might be that your data processor should not be shared. In such case
you need to set the :yaml:`shared: false` tag attribute for the service.
Impact
======
Data processors can now be tagged with the :yaml:`data.processor` tag. This
allows to define an alias / identifier, which can then be used instead of
the fully-qualified class name, e.g. in TypoScript configurations.
.. index:: TypoScript, Frontend, ext:frontend
@@ -0,0 +1,42 @@
.. include:: /Includes.rst.txt
.. _feature-97309:
================================================================
Feature: #97309 - Differentiate redirects based on creation type
================================================================
See :issue:`97309`
Description
===========
A new field :sql:`creation_type` has been added to the :sql:`sys_redirect` table.
This allows to differentiate between redirects created automatically when the
slug of a page has changed and the ones which are created in the backend
module by editors.
A new option in the :guilabel:`Redirects` module allows to filter by this type.
Impact
======
The distinction by the creation type helps users to administrate the redirect
records and helps to identify why a record has been created initially.
An update wizard updates all existing redirects and sets the type to "manual".
If desired, the available items of the field :sql:`creation_type` can be extended
with additional types by adjusting TCA for this field. This simplifies the
registration of additional types, which are automatically available in the backend
filtering. Possible use cases are, for example, synchronized redirects or migrated
from other / old sources sources.
.. code-block:: php
$GLOBALS['TCA']['sys_redirect']['columns']['creation_type']['config']['items'][] = [
'My extension redirects',
91,
];
.. index:: Backend, ext:redirects
@@ -0,0 +1,32 @@
.. include:: /Includes.rst.txt
.. _feature-97391:
=======================================================================
Feature: #97391 - Use password policy for password reset in ext:backend
=======================================================================
See :issue:`97391`
Description
===========
The password reset feature for TYPO3 backend users now considers the
configurable password policy introduced in :ref:`#97388 <feature-97388>`.
Impact
======
The formerly hardcoded minimum length of 8 chars for the new password
has been removed. Instead, the globally configured password policy is now
taken into account when a TYPO3 backend user resets the password. The
TYPO3 default password policy contains the following password requirements:
* At least 8 chars
* At least one number
* At least one upper case char
* At least one special char
* Must be different than current password (if available)
.. index:: Backend, ext:backend
@@ -0,0 +1,43 @@
.. include:: /Includes.rst.txt
.. _feature-97536-1651523601:
======================================================
Feature: #97536 - Unified API for generating typolinks
======================================================
See :issue:`97536`
Description
===========
A new :php:`\TYPO3\CMS\Frontend\Typolink\LinkFactory` class is added to TYPO3
Core, which allows to generate any kind of links in the TYPO3 frontend - links
to files, pages, URLs, email, telephone links, or links to specific records,
such as news entries.
Previously, this functionality resided in :php:`ContentObjectRenderer->typoLink()`
and :php:`ContentObjectRenderer->typoLink_URL()` but was extracted into a
specific class, only dealing with the generation of links.
This class works with two main methods:
:php:`LinkFactory->create()`
:php:`LinkFactory->createUri()`
Both methods return a :php:`LinkResultInterface` instance, which can be used
programmatically to render the results of the link generation for HTML output
via :php:`LinkResult->getHtml()` or as JSON with :php:`LinkResult->getJson()`.
Impact
======
For TypoScript or Fluid-based renderings, the base functionality for using
:php:`ContentObjectRenderer->typoLink()` is still recommended. However, when
an extension developer wants to work with the raw result, the
:php:`LinkResultInterface` and corresponding implementations for JSON and HTML
rendering allow for much more flexibility by accessing more information than
just the raw anchor tag.
.. index:: Frontend, PHP-API, ext:frontend
@@ -0,0 +1,58 @@
.. include:: /Includes.rst.txt
.. _feature-97747-1654691279:
===========================================
Feature: #97747 - Introduce MailerInterface
===========================================
See :issue:`97747`
Description
===========
To be able to use your own custom mailer implementation in the TYPO3 Core, an
interface :php:`\TYPO3\CMS\Core\Mail\MailerInterface` is introduced, which extends
:php:`\Symfony\Component\Mailer\MailerInterface`
By default, :php:`\TYPO3\CMS\Core\Mail\Mailer` is registered as implementation in
:file:`Configuration/Services.yaml`.
Example
-------
.. code-block:: php
use TYPO3\CMS\Core\Mail\MailerInterface;
class MyClass
{
public function __construct(
private readonly MailerInterface $mailer
) {
}
}
Or where constructor injection is not possible:
.. code-block:: php
$mailer = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailerInterface::class);
Impact
======
This change makes it possible to create your own :php:`\My\Custom\Mailer` that implements
:php:`\TYPO3\CMS\Core\Mail\MailerInterface` which is used by TYPO3 core. Therefore, it is recommended
to use the interface :php:`\TYPO3\CMS\Core\Mail\MailerInterface`, to let dependency injection inject the
desired implementation for every :php:`\TYPO3\CMS\Core\Mail\MailerInterface`.
Add the following line in :file:`Configuration/Services.yaml`, to ensure that your custom
implementation can be injected.
.. code-block:: yaml
TYPO3\CMS\Core\Mail\MailerInterface:
alias: My\Custom\Mailer
.. index:: PHP-API, ext:core
@@ -0,0 +1,89 @@
.. include:: /Includes.rst.txt
.. _feature-98373-1663587471:
=========================================================
Feature: #98373 - Reactions - Incoming webhooks for TYPO3
=========================================================
See :issue:`98373`
Description
===========
This feature adds the possibility to receive webhooks in TYPO3.
With the new :guilabel:`System > Reactions` backend module it is possible to
configure the reactions triggered by any webhook.
A webhook is defined as an authorized POST request to the backend.
The core provides a basic default reaction that can be used to create
records triggered and enriched by data from the caller.
Additionally, the Core provides the :php:`\TYPO3\CMS\Reactions\Reaction\ReactionInterface`
to allow extension authors to add their own reaction types.
Any reaction record is defined by a unique uid (UUID) and also requires a secret.
Both information are generated in the backend. The secret is only visible once and
stored in the database as an encrypted value like a backend user password.
Next to static field values, the "create record" reaction features placeholders,
which can be used to dynamically set field values by resolving the incoming
data from the webhook's payload. The syntax for those values is :code:`${key}`.
The key can be a simple string or a path to a nested value like :code:`${key.nested}`.
Definition of the placeholders in the record
--------------------------------------------
.. code-block:: text
${title}
${description}
${key.nested}
Example payload for placeholders
--------------------------------
.. code-block:: json
{
"title": "My title",
"description": "My description",
"key": {
"nested": "bar"
}
}
By default, only a few tables can be selected for external creation in the
create record reaction. In case you want to allow your own tables to be
available in the reactions' table selection, add the table in a corresponding TCA
override file with:
.. code-block:: php
if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('reactions')) {
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItem(
'sys_reaction',
'table_name',
[
'label' => 'LLL:EXT:myext/Resources/Private/Language/locallang.xlf:my_table',
'value' => 'my_table',
'icon' => 'myext-my_table-icon',
]
);
}
In case your extension depends on EXT:reactions the :php:`isLoaded()` check
might be skipped. Please note that tables with :php:`adminOnly` set are not
allowed.
Impact
======
This feature allows everybody to provide additional value for any TYPO3 instance.
By reacting to webhooks, TYPO3 can now be used to create records in the backend.
Furthermore, by implementing the :php:`ReactionInterface`, it is possible to
create any custom reaction.
.. index:: Backend, ext:reactions
@@ -0,0 +1,71 @@
.. include:: /Includes.rst.txt
.. _feature-98521-1664890745:
=====================================================================
Feature: #98521 - PSR-14 event to modify form data for edit file form
=====================================================================
See :issue:`98521`
Description
===========
A new PSR-14 event :php:`TYPO3\CMS\Filelist\Event\ModifyEditFileFormDataEvent`
has been added, which allows to modify the form data used to render the
file edit form in the :guilabel:`File > Filelist` module using
:ref:`FormEngine data compiling <t3coreapi:FormEngine-DataCompiling>`.
The new event can be used as an improved alternative for the removed
:php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['preOutputProcessingHook']`
hook.
The event features the following methods:
- :php:`getFormData()`: Returns the current :php:`$formData` array
- :php:`setFormData()`: Sets the :php:`$formData` array
- :php:`getFile()`: Returns the corresponding :php:`\TYPO3\CMS\Core\Resource\FileInterface`
- :php:`getRequest()`: Returns the full PSR-7 :php:`\Psr\Http\Message\ServerRequestInterface`
Registration of the event in your extension's :file:`Services.yaml`:
.. code-block:: yaml
MyVendor\MyPackage\EventListener\ModifyEditFileFormDataEventListener:
tags:
- name: event.listener
identifier: 'my-package/modify-edit-file-form-data-event-listener'
The corresponding event listener class:
.. code-block:: php
use TYPO3\CMS\Filelist\Event\ModifyEditFileFormDataEvent;
final class ModifyEditFileFormDataEventListener
{
public function __invoke(ModifyEditFileFormDataEvent $event): void
{
// Get current form data
$formData = $event->getFormData();
// Change TCA "renderType" based on the file extension
$fileExtension = $event->getFile()->getExtension();
if ($fileExtension === 'ts') {
$formData['processedTca']['columns']['data']['config']['renderType'] = 'tsRenderer';
}
// Set updated form data
$event->setFormData($formData);
}
}
Impact
======
It is now possible to modify the whole :php:`$formData` array used to generate
the edit file form in the :guilabel:`File > Filelist` module, while having the
resolved :php:`FileInterface` and the current PSR-7 :php:`ServerRequestInterface`
available.
.. index:: Backend, PHP-API, ext:filelist
@@ -0,0 +1,115 @@
.. include:: /Includes.rst.txt
.. _feature-98540:
===========================================================
Feature: #98540 - New TCA field control "passwordGenerator"
===========================================================
See :issue:`98540`
Description
===========
A new TCA field control :php:`passwordGenerator` has been introduced,
which can be used in combination with TCA type `password`. The control
renders a button next to the password field allowing the user to generate
a random password based on defined rules.
Using the control adds the generated password to the corresponding field.
The password is visible to the backend user only once and stored encrypted
in the database. Integrators are also able to define whether the user
is allowed to edit the generated password before saving.
Example configuration
---------------------
.. code-block:: php
'password_field' => [
'label' => 'Password',
'config' => [
'type' => 'password',
'fieldControl' => [
'passwordGenerator' => [
'renderType' => 'passwordGenerator',
'options' => [
'title' => 'Generate a password',
'allowEdit' => false,
'passwordRules' => [
'length' => 38,
'digitCharacters' => false,
'specialCharacters' => true,
],
],
],
],
],
],
This example will add the control with a custom title. The generated password
will be 38 characters long, will contain lowercase, uppercase and special
characters and no digit characters. The user won't be able to edit the
generated password.
Field control options
---------------------
- :php:`title`: Define a title for the control button
- :php:`allowEdit`: Whether the user can edit the generated password
- :php:`passwordRules`: Define rules for the password.
Available password rules:
- :php:`length`: Defines the number of characters for the password
(minimum: :php:`8` - default: :php:`16`).
- :php:`random`: Defines the encoding of random bytes. Overrules character
definitions. Available encodings are :php:`hex` and :php:`base64`.
- :php:`digitCharacters`: Whether digits should be used (Default: :php:`true`)
- :php:`lowerCaseCharacters`: Whether lowercase characters should be used
(Default: :php:`true`)
- :php:`upperCaseCharacters`: Whether uppercase characters should be used
(Default: :php:`true`)
- :php:`specialCharacters`: Whether special characters should be used
(Default: :php:`false`)
Random bytes
------------
The following example will generate a 40 characters long random hex string, which
could be used e.g. for secret tokens or similar:
.. code-block:: php
'random_hex' => [
'label' => 'Random hex',
'config' => [
'type' => 'password',
'fieldControl' => [
'passwordGenerator' => [
'renderType' => 'passwordGenerator',
'options' => [
'passwordRules' => [
'length' => 40,
'random' => 'hex',
],
],
],
],
],
],
.. note::
Defining the special :php:`random` password rule always takes
precedence over any character definition, which should therefore
be omitted as soon as :php:`random` is set to one of the available
encodings: :php:`hex` or :php:`base64`.
Impact
======
It is now possible to enhance the TCA type `password` with a field control
to generate a random password based on defined password rules.
.. index:: TCA, ext:backend
@@ -0,0 +1,54 @@
.. include:: /Includes.rst.txt
.. _feature-98912-1667814888:
==========================================================
Feature: #98912 - Installation-wide services configuration
==========================================================
See :issue:`98912`
Description
===========
It is possible to set up a global services configuration for a
project that can be used in multiple project-specific extensions. This way you
can, for example, alias an interface with a concrete implementation to be used in
several extensions. It is also possible to register project-specific CLI commands
without having the need for a project-specific extension.
However, this only works - due to security restrictions - if TYPO3 is configured
in a way that the project root is outside the document root, which usually
happens in Composer-based installations.
Impact
======
The global services configuration files :file:`services.yaml` and
:file:`services.php` are now read within the :file:`config/system/` path
of a TYPO3 project in Composer-based installations.
Example
-------
You want to use the interface of the PHP package `stella-maris/clock` as type
hint for DI in the service classes of your project's various extensions. Then
the concrete implementation may change without touching your code. In this
example we use `lcobucci/clock` for the concrete implementation.
.. code-block:: php
:caption: config/system/services.php
use Lcobucci\Clock\SystemClock;
use StellaMaris\Clock\ClockInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator, ContainerBuilder $containerBuilder): void {
$services = $containerConfigurator->services();
$services->set(ClockInterface::class)
->factory([SystemClock::class, 'fromUTC']);
};
.. index:: ext:core
@@ -0,0 +1,94 @@
.. include:: /Includes.rst.txt
.. _feature-98914-1666689687:
=================================================
Feature: #98914 - TypoScript as request attribute
=================================================
See :issue:`98914`
Description
===========
The TYPO3 frontend middleware chain now sets up the request
attribute :php:`frontend.typoscript`. This is an instance of
:php:`\TYPO3\CMS\Core\TypoScript\FrontendTypoScript` and contains
the calculated TypoScript :php:`settings` (formerly "constants") and
sometimes :php:`setup`, depending on page cache status.
When a content object or plugin (plugins are content objects as well) needs the
current TypoScript, it can retrieve it using this API:
.. code-block:: php
// New substitution of $GLOBALS['TSFE']->tmpl->setup
$frontendTypoScriptSetupArray = $request->getAttribute('frontend.typoscript')->getSetupArray();
The :php:`FrontendTypoScript` attribute contains some more getters:
* :php:`getSettingsTree()`: The TypoScript settings as object tree. This tree is still
a bit experimental in TYPO3 v12 and should only be used if really needed for now, it
may still change. It is marked internal at the moment.
The constants tree is *always* set up in frontend requests: It is needed early for page
cache determination, content objects can expect it to be set.
* :php:`getFlatSettings()`: The TypoScript settings as flat array. Example TypoScript:
.. code-block:: typoscript
mySettings {
foo = fooValue
bar = barValue
}
Result array:
.. code-block:: php
$flatSettings = [
'mySettings.foo' => 'fooValue',
'mySettings.bar' => 'barValue',
];
The settings array is *always* set up in frontend requests: It is needed early for page
cache determination, content objects can expect it to be set.
* :php:`getSetupTree()`: The TypoScript setup as object tree. This tree is still
a bit experimental in TYPO3 v12 and should only be used if really needed for now, it
may still change. It is marked internal at the moment.
The setup tree is only set up, if a frontend request could not be satisfied from page
cache and a full page content calculation is required, or if a page cache does exist,
but contains :typoscript:`USER_INT` or :typoscript:`COA_INT` that have to be calculated
for each call. Effectively, when a content object rendering is called, the object can
expect the setup object tree to be set.
* :php:`getSetupArray()`: An array representation of the setup tree. This is identical to
the old :php:`TYPO3\CMS\Core\TypoScript\TemplateService->setup` that was usually accessed
using :php:`$GLOBALS['TSFE']->tmpl->setup`.
This is the main API to retrieve frontend TypoScript for now. Content objects do receive
the current request from the rendering chain and can retrieve the full TypoScript this way,
if needed. Note that content objects also retrieve the "local" content object configuration
already, an access to the full TypoScript in general is only needed in seldom cases.
The setup array is only set up if a frontend request could not be satisfied from page
cache and a full page content calculation is required, or if a page cache does exist
but contains :typoscript:`USER_INT` or :typoscript:`COA_INT` that have to be calculated
for each call. Effectively, when a content object rendering is called, the object can
expect the setup object tree to be set.
Impact
======
This is a substitution especially of the deprecated :php:`TYPO3\CMS\Core\TypoScript\TemplateService`,
typical old calls were :php:`TypoScriptFrontendController->tmpl` or :php:`$GLOBALS['TSFE']->tmpl`,
often reading the :php:`setup` property using :php:`tmpl->setup` to grab the current TypoScript
setup array. These calls should be avoided, the :php:`TemplateService` and the :php:`tmpl`
property will be removed in TYPO3 v13.
.. index:: Frontend, PHP-API, TypoScript, ext:frontend
@@ -0,0 +1,42 @@
.. include:: /Includes.rst.txt
.. _feature-98921-1666766437:
=============================================================================
Feature: #98921 - Get multiple items by common key prefix from local storages
=============================================================================
See :issue:`98921`
Description
===========
A new method :js:`getByPrefix()` is added to the module
:js:`@typo3/backend/storage/abstract-client-storage`, affecting its
implementations
* :js:`@typo3/backend/storage/browser-session`
* :js:`@typo3/backend/storage/client`
Impact
======
A developer is now able to obtain multiple items prefixed by a given key either
from :js:`localStorage` or :js:`sessionStorage`.
Example:
.. code-block:: js
import Client from '@typo3/backend/storage/client';
Client.set('common-prefix-a', 'a');
Client.set('common-prefix-b', 'b');
Client.set('common-prefix-c', 'c');
const entries = Client.getByPrefix('common-prefix-');
// {'common-prefix-a': 'a', 'common-prefix-b': 'b', 'common-prefix-c': 'c'}
.. index:: JavaScript, ext:backend
@@ -0,0 +1,28 @@
.. include:: /Includes.rst.txt
.. _feature-98957-1667131640:
======================================================================
Feature: #98957 - Respect write-protected settings.php in Install Tool
======================================================================
See :issue:`98957`
Description
===========
The :guilabel:`Admin Tools > Settings` backend module now informs a system
maintainer if the :file:`system/settings.php` file is write-protected.
This allows to make the settings file read-only after deployments.
Impact
======
An info box is rendered in the module and each submodule, informing the system
maintainer that the :file:`system/settings.php` file is write-protected.
In that case, all input fields are disabled and the submit buttons are not
available.
.. index:: LocalConfiguration, ext:install
@@ -0,0 +1,29 @@
.. include:: /Includes.rst.txt
.. _feature-99011-1667944274:
==================================================
Feature: #99011 - Allow descriptions for redirects
==================================================
See :issue:`99011`
Description
===========
A new field :sql:`description` has been added to the :sql:`sys_redirect` table.
In the backend edit form, the new field is located under the :guilabel:`Notes`
tab. It can be used to add context to the corresponding redirect. Since the
field is defined as the record's :php:`descriptionColumn`, the added
information is also displayed in the "Record information" info box
above the edit form, like known from e.g. content elements or pages.
Impact
======
It is now possible to add additional information to a redirect
using the new description field, whose value is also displayed
in the corresponding backend edit form.
.. index:: Database, TCA, Backend
@@ -0,0 +1,67 @@
.. include:: /Includes.rst.txt
.. _feature-99033-1668008969:
=====================================================
Feature: #99033 - Add table filter for backend search
=====================================================
See :issue:`99033`
Description
===========
The TYPO3 backend search (aka "Live Search") is using the
:php:`\TYPO3\CMS\Backend\Search\LiveSearch\DatabaseRecordProvider` to search
for records in database tables, having :php:`searchFields` configured in TCA.
In some individual cases, it may not be desired to search in a certain table.
Therefore, the new event :php:`\TYPO3\CMS\Backend\Search\Event\BeforeSearchInDatabaseRecordProviderEvent`
has been introduced, which allows to exclude / ignore such tables by adding them
to a deny list. Additionally, the new PSR-14 event can be used to further
limit the search result on certain page IDs or to modify the search query
altogether.
The event features the following methods:
- :php:`getSearchPageIds()`: Returns the page ids to search in
- :php:`setSearchPageIds()`: Allows to define page ids to search in
- :php:`getSearchDemand()`: Returns the :php:`SearchDemand`, used by the live search
- :php:`setSearchDemand()`: Allows to set a custom :php:`SearchDemand` object
- :php:`ignoreTable()`: Allows to ignore / exclude a table from the lookup
- :php:`setIgnoredTables()`: Allows to overwrite the ignored tables
- :php:`isTableIgnored()`: Returns whether a specific table is ignored
- :php:`getIgnoredTables()`: Returns all tables to be ignored from the lookup
Registration of the event in your extension's :file:`Services.yaml`:
.. code-block:: yaml
MyVendor\MyPackage\EventListener\BeforeSearchInDatabaseRecordProviderEventListener:
tags:
- name: event.listener
identifier: 'my-package/before-search-in-database-record-provider-event-listener'
The corresponding event listener class:
.. code-block:: php
use TYPO3\CMS\Backend\Search\Event\BeforeSearchInDatabaseRecordProviderEvent;
final class ModifyEditFileFormDataEventListener
{
public function __invoke(BeforeSearchInDatabaseRecordProviderEvent $event): void
{
$event->ignoreTable('my_custom_table');
}
}
Impact
======
It is now possible to ignore specific tables from the backend search using
the new PSR-14 event :php:`BeforeSearchInDatabaseRecordProviderEvent`. The event
also allows to adjust the page IDs to search in as well as to modify the
corresponding :php:`SearchDemand` object.
.. index:: Backend, PHP-API, ext:backend
@@ -0,0 +1,25 @@
.. include:: /Includes.rst.txt
.. _feature-99038-1668093242:
=========================================
Feature: #99038 - Overview for file mounts
=========================================
See :issue:`99038`
Description
===========
A new submodule was added to the :guilabel:`Backend Users` module. It provides an
overview over all available file mounts with detailed data. Additionally an info
window displays also the references to the file mount.
Impact
======
It is now possible to get an overview about available file mounts
without switching to the :guilabel:`List` module on pid=0.
.. index:: Database, TCA, Backend
@@ -0,0 +1,46 @@
.. include:: /Includes.rst.txt
.. _feature-99047-1668081474:
================================================================
Feature: #99047 - Load site settings from separate settings.yaml
================================================================
See :issue:`99047`
Description
===========
Site settings have been introduced with TYPO3 v10 as part of the configuration
of a site. In contrast to the site configuration, they are mostly used to
provide sane defaults for TypoScript constants and have a layer of arbitrary
configuration available in any context.
In order to separate these settings from the system site configuration, make them
accessible and editable in the TYPO3 backend, and to distinguish between required
site configuration and optional settings, the "settings" part of the settings are
copied to a separate :file:`settings.yaml` file in the site configuration folder.
A migration wizard is provided as upgrade wizard to migrate settings into the
new file.
.. note::
Settings are not removed from the :file:`config.yaml` for now but will not
have any effect anymore as soon as a :file:`settings.yaml` exists.
Please review your settings in the :file:`config.yaml` and remove them
manually. Eventually, you need and/or want to adopt your deployment
workflow.
Impact
======
Settings are now loaded from a separate file called :file:`settings.yaml` residing
next to the :file:`config.yaml` of a site.
Executing the upgrade wizard will load all settings of a site and create that
file for the user. The migration wizard will not remove / rewrite the
:file:`config.yaml` - the user should do that on their own, to avoid breaking
custom-built functionality.
.. index:: Backend, YAML, ext:core
@@ -0,0 +1,59 @@
.. include:: /Includes.rst.txt
.. _feature-99048-1668081533:
========================================
Feature: #99048 - Site settings read API
========================================
See :issue:`99048`
Description
===========
Settings for site-specific functionality can now be retrieved by a dedicated
:php:`\TYPO3\CMS\Core\Site\Entity\SiteSettings` object, accessible via a
:php:`\TYPO3\CMS\Core\Site\Entity\Site` object like :php:`$site->getSettings()`.
Settings can be used in custom frontend code to deliver features which might
vary per-site for extensions.
Impact
======
Accessing site settings, which was previously possible via:
:php:`$site->getConfiguration()['settings']['redirects'] ?? []`
in custom PHP code, is now easier via the :php:`SiteSettings` PHP object.
The :php:`SiteSettings` object can be used to access settings either by
the dot notation ("flat", a default value can be given as optional second
argument), e.g.:
.. code-block:: php
$redirectStatusCode = (int)$siteSettings->get('redirects.httpStatusCode', 307);
or by accessing all options for a certain group:
.. code-block:: php
$allSettingsRelatedToRedirects = $siteSettings->get('redirects');
or even fetching all settings:
.. code-block:: php
$allSettings = $siteSettings->all();
In addition, settings can now be accessed in TypoScript via :typoscript:`getData`
with the key :typoscript:`siteSettings`:
.. code-block:: typoscript
page.10 = TEXT
page.10.data = siteSettings:redirects.httpStatusCode
.. index:: PHP-API, TypoScript ext:core
@@ -0,0 +1,74 @@
.. include:: /Includes.rst.txt
.. _feature-99053-1668163567:
======================================================
Feature: #99053 - Route aspect fallback value handling
======================================================
See :issue:`99053`
Description
===========
Imagine a route like `/news/{news_title}` that has been filled with an
"invalid" value for the `news_title` part. Often these are outdated, deleted
or hidden records. Usually TYPO3 reacts to these "invalid" URL sections at a
very early stage with an HTTP status code `404` (resource not found).
The new property `fallbackValue = [string|null]` can prevent the above scenario
in several ways. By specifying an alternative value, a different record,
language or other detail can be represented. Specifying `null` removes the
corresponding parameter from the route result. In this way, it is up to the
developer to react accordingly.
In the case of Extbase extensions, the developer can define the parameters in
their calling controller action as nullable and deliver corresponding
flash messages that explain the current scenario better than a 404 HTTP
status code.
Examples
--------
.. code-block:: yaml
routeEnhancers:
NewsPlugin:
type: Extbase
extension: News
plugin: Pi1
routes:
- routePath: '/detail/{news_title}'
_controller: 'News::detail'
_arguments:
news_title: 'news'
aspects:
news_title:
type: PersistedAliasMapper
tableName: tx_news_domain_model_news
routeFieldName: path_segment
# string values lead to parameter `&tx_news_pi1[news]=0`
fallbackValue: '0'
# null values lead to parameter `&tx_news_pi1[news]` being removed
fallbackValue: null
Custom mapper implementations can incorporate this behavior by implementing
the new :php:`\TYPO3\CMS\Core\Routing\Aspect\UnresolvedValueInterface` which
is provided by :php:`\TYPO3\CMS\Core\Routing\Aspect\UnresolvedValueTrait`.
.. code-block:: php
use TYPO3\CMS\Core\Routing\Aspect\MappableAspectInterface;
use TYPO3\CMS\Core\Routing\Aspect\UnresolvedValueInterface;
use TYPO3\CMS\Core\Routing\Aspect\UnresolvedValueTrait;
class MyCustomEnhancer implements MappableAspectInterface, UnresolvedValueInterface
{
use UnresolvedValueTrait;
// ...
}
.. index:: Frontend, YAML, ext:core
@@ -0,0 +1,47 @@
.. include:: /Includes.rst.txt
.. _feature-99055-1668096727:
=========================================================
Feature: #99055 - BackendController service tag attribute
=========================================================
See :issue:`99055`
Description
===========
A new PHP attribute :php:`TYPO3\CMS\Backend\Attribute\AsController` has
been added in order to register services to the BackendController dependency
injection container.
.. note::
In early TYPO3 v12 versions the attribute was named :php:`#[Controller]` and
has later been renamed to :php:`#[AsController]`. Both work with TYPO3 v12,
but developers should use :php:`#[AsController]` for upwards compatibility
since :php:`#[Controller]` has been deprecated with TYPO3 v13.
In addition to tag :yaml:`backend.controller` in the :file:`Services.yaml` file,
tagging services as backend controller can be done like:
Example implementation
----------------------
.. code-block:: php
use TYPO3\CMS\Backend\Attribute\AsController;
#[AsController]
class MyBackendController {
}
Impact
======
It is now possible to tag services as backend controller by the PHP attribute
:php:`TYPO3\CMS\Backend\Attribute\AsController` instead of tagging them with
:yaml:`backend.controller` in the :file:`Services.yaml` file.
.. index:: Backend
@@ -0,0 +1,52 @@
.. include:: /Includes.rst.txt
.. _feature-99062-1668170141:
=====================================================================
Feature: #99062 - Native JSON database field support in Doctrine DBAL
=====================================================================
See :issue:`99062`
Description
===========
TYPO3 Core's Database API based on Doctrine DBAL now supports the native
database field type `json`, which is already available for all supported DBMS
of TYPO3 v12.
JSON-like objects or arrays are automatically serialized during writing a
dataset to the database, when the native JSON type was used in the database
schema definition.
Impact
======
By using the native database field declaration `json` in e.g. :file:`ext_tables.sql`
files within an extension, TYPO3 now converts arrays or objects of type
:php:`\JsonSerializable` into a serialized JSON value in the database when
persisting such values via :php:`Connection->insert()` or
:php:`Connection->update()`, if no explicit database types are handed in as additional
method argument.
TYPO3 now utilizes the native type mapping of Doctrine to convert special types,
such as JSON database field types automatically for writing.
Example :file:`ext_tables.sql`:
.. code-block:: sql
CREATE TABLE tx_myextension_domain_model_book (
title varchar(200) DEFAULT '',
contents json
);
.. note::
However, when reading a record from the database via QueryBuilder, it is
still necessary to transfer the serialized value to an array or object,
performing a custom serialization for the time being.
.. index:: Database, ext:core
@@ -0,0 +1,53 @@
.. include:: /Includes.rst.txt
.. _feature-99084-1667981931:
========================================================
Feature: #99084 - Make context menu trigger configurable
========================================================
See :issue:`99084`
Description
===========
The context menu JavaScript API was adapted to also support opening
the menu through the "contextmenu" event type (right click) only.
Configuration for the context menu was streamlined and now reflects
its purpose. The trigger can now be set to "click" or "contextmenu".
New options
-----------
:html:`data-contextmenu-trigger`:
- :html:`click`: Opens the context menu on "click" and on "contextmenu"
- :html:`contextmenu`: Opens the context menu only on "contextmenu"
Examples
--------
.. code-block:: html
<a href="#"
data-contextmenu-trigger="click"
data-contextmenu-table="pages"
data-contextmenu-uid="10"
>Click and Contextmenu</a>
.. code-block:: html
<a href="#"
data-contextmenu-trigger="contextmenu"
data-contextmenu-table="pages"
data-contextmenu-uid="10"
>Contextmenu only</a>
Impact
======
It is now possible to bind the context menu only to the
event type "contextmenu".
.. index:: Backend, JavaScript
@@ -0,0 +1,53 @@
.. include:: /Includes.rst.txt
.. _feature-99092-1668509154:
==================================================
Feature: #99092 - Allow static backdrops in modals
==================================================
See :issue:`99092`
Description
===========
The Modal API is now able to render a static backdrop to avoid closing the modal
when clicking it. This may be handy in case closing the modal would result in
a negative user experience, e.g. in the image cropper.
Impact
======
The new boolean configuration option :js:`staticBackdrop` controls whether a
static backdrop should be rendered or not; the default is :js:`false`.
Example:
.. code-block:: js
import Modal from '@typo3/backend/modal';
Modal.advanced({
title: 'Hello',
content: 'This modal is not closable via clicking the backdrop.',
size: Modal.sizes.small,
staticBackdrop: true
});
Templates using the HTML class :html:`.t3js-modal-trigger` to initialize
a modal dialog can also use the new option by adding the
:html:`data-static-backdrop` attribute to the corresponding element.
Example:
.. code-block:: html
<button class="btn btn-default t3js-modal-trigger"
data-title="Hello"
data-bs-content="This modal is not closable via clicking the backdrop."
data-static-backdrop>
Open modal
</button>
.. index:: Backend, JavaScript, ext:backend
@@ -0,0 +1,160 @@
.. include:: /Includes.rst.txt
.. _feature-99093-1668065501:
====================================================
Feature: #99093 - Introduce DropDownButton component
====================================================
See :issue:`99093`
Description
===========
The module menu button bar now can display dropdowns.
This enables new interface interactions, like switching
the current view from list to tiles or group actions
like clipboard and thumbnail visibility. It make the views
clearer and the user to see more information at a glance.
Each dropdown consists of different items ranging from
headlines to item links that can display the current
status. The button automatically changes the icon
representation to the icon of the first active radio
icon in the dropdown list.
DropDownButton
--------------
This button type is a container for dropdown items.
It will render a dropdown containing all items attached
to it. There are different kinds available, each item
needs to implement the
:php:`\TYPO3\CMS\Backend\Template\Components\Buttons\DropDown\DropDownItemInterface`.
When this type contains elements of type
:php:`\TYPO3\CMS\Backend\Template\Components\Buttons\DropDown\DropDownRadio` it
will use the icon of the first active item of this type.
.. code-block:: php
$buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
$dropDownButton = $buttonBar->makeDropDownButton()
->setLabel('Dropdown')
->setTitle('Save')
->setIcon($this->iconFactory->getIcon('actions-heart'))
->addItem(
GeneralUtility::makeInstance(DropDownItem::class)
->setLabel('Item')
->setHref('#')
);
$buttonBar->addButton($dropDownButton, ButtonBar::BUTTON_POSITION_RIGHT, 2);
DropDown\DropDownDivider
------------------------
This dropdown item type renders the divider element.
.. code-block:: php
// use TYPO3\CMS\Backend\Template\Components\Buttons\DropDown\DropDownDivider;
$item = GeneralUtility::makeInstance(DropDownDivider::class);
$dropDownButton->addItem($item);
DropDown\DropDownHeader
-----------------------
This dropdown item type renders a non-interactive text
element to group items and gives more meaning to a set
of options.
.. code-block:: php
// use TYPO3\CMS\Backend\Template\Components\Buttons\DropDown\DropDownHeader;
$item = GeneralUtility::makeInstance(DropDownHeader::class)
->setLabel('Label');
$dropDownButton->addItem($item);
DropDown\DropDownItem
---------------------
This dropdown item type renders a simple element.
Use this element if you need a link, button.
.. code-block:: php
// use TYPO3\CMS\Backend\Template\Components\Buttons\DropDown\DropDownItem;
$item = GeneralUtility::makeInstance(DropDownItem::class)
->setTag('a')
->setHref('#')
->setLabel('Label')
->setTitle('Title')
->setIcon($this->iconFactory->getIcon('actions-heart'))
->setAttributes(['data-value' => '123']);
$dropDownButton->addItem($item);
DropDown\DropDownRadio
----------------------
This dropdown item type renders an element with an active state.
Use this element to display a radio-like selection of a state.
When set to active, it will show a dot in front of the icon and
text to indicate that this is the current selection.
At least 2 of these items need to exist within a dropdown button,
so a user has a choice of a state to select.
Example: Viewmode -> List / Tiles
.. code-block:: php
// use TYPO3\CMS\Backend\Template\Components\Buttons\DropDown\DropDownRadio;
$item = GeneralUtility::makeInstance(DropDownRadio::class)
->setHref('#')
->setActive(true)
->setLabel('List')
->setTitle('List')
->setIcon($this->iconFactory->getIcon('actions-viewmode-list'))
->setAttributes(['data-type' => 'list']);
$dropDownButton->addItem($item);
$item = GeneralUtility::makeInstance(DropDownRadio::class)
->setHref('#')
->setActive(false)
->setLabel('Tiles')
->setTitle('Tiles')
->setIcon($this->iconFactory->getIcon('actions-viewmode-tiles'))
->setAttributes(['data-type' => 'tiles']);
$dropDownButton->addItem($item);
DropDown\DropDownToggle
-----------------------
This dropdown item type renders an element with an active state.
When set to active, it will show a checkmark in front of the icon
and text to indicate the current state.
.. code-block:: php
// use TYPO3\CMS\Backend\Template\Components\Buttons\DropDown\DropDownToggle;
$item = GeneralUtility::makeInstance(DropDownToggle::class)
->setHref('#')
->setActive(true)
->setLabel('Label')
->setTitle('Title')
->setIcon($this->iconFactory->getIcon('actions-heart'))
->setAttributes(['data-value' => '123']);
$dropDownButton->addItem($item);
.. index:: Backend, ext:backend
@@ -0,0 +1,72 @@
.. include:: /Includes.rst.txt
.. _feature-99118:
=====================================================================
Feature: #99118 - PSR-14 event to define whether files are selectable
=====================================================================
See :issue:`99118`
Description
===========
A new PSR-14 event :php:`\TYPO3\CMS\Backend\ElementBrowser\Event\IsFileSelectableEvent`
has been introduced. It allows to define whether a file can be selected in the
file browser. Previously, this was only possible by overriding the
:php:`\TYPO3\CMS\Backend\ElementBrowser\FileBrowser->fileIsSelectableInFileList()`
method via an XCLASS.
The event features the following methods:
- :php:`getFile()`: Returns the :php:`\TYPO3\CMS\Core\Resource\FileInterface` in question
- :php:`isFileSelectable()`: Whether the file is allowed to be selected
- :php:`allowFileSelection()`: Allow selection of the file in question
- :php:`denyFileSelection()`: Deny selection of the file in question
.. note::
The :php:`fileIsSelectableInFileList()` method allowed to access the image
dimensions (`width` and `height`) via the second parameter :php:`$imgInfo`.
Those information however can be retrieved directly from the :php:`FileInterface`
in a more convenient way using the :php:`getProperty()` method. Therefore,
the new Event does not provide this parameter explicitly.
Registration of the event in your extension's :file:`Services.yaml`:
.. code-block:: yaml
:caption: EXT:my_extension/Configuration/Services.yaml
MyVendor\MyExtension\Backend\MyEventListener:
tags:
- name: event.listener
identifier: 'my-extension/backend/modify-file-is-selectable'
The corresponding event listener class:
.. code-block:: php
:caption: EXT:my_extension/Classes/Backend/MyEventListener.php
namespace MyVendor\MyExtension\Backend;
use TYPO3\CMS\Backend\ElementBrowser\Event\IsFileSelectableEvent;
final class MyEventListener {
public function __invoke(IsFileSelectableEvent $event): void
{
// Deny selection of "png" images
if ($event->getFile()->getExtension() === 'png') {
$event->denyFileSelection();
}
}
}
Impact
======
It is now possible to decide whether a file can be selected in the
file browser, using an improved PSR-14 approach instead
of cross classing.
.. index:: Backend, ext:backend
@@ -0,0 +1,36 @@
.. include:: /Includes.rst.txt
.. _feature-99155-1669116236:
===========================================
Feature: #99155 - Add tile view to filelist
===========================================
See :issue:`99155`
Description
===========
The listing of resources in a table has some specific use
cases, but it is hard for the editor to get an overview of file
resources since the thumbnails are small.
To provide a better overview of assets in the :guilabel:`Filelist` module we
are introducing a tile view with bigger thumbnails and reduced
meta information. The user can now choose the desired display
mode of the assets depending on the current requirements.
The user can change the view mode in the view menu in the
module menu bar. By default the tile view is enabled for
new and existing users.
TYPO3 will remember the choice of the user.
Impact
======
The user can now change the display mode of resources
in the :guilabel:`Filelist` module.
.. index:: Backend, ext:filelist
@@ -0,0 +1,25 @@
.. include:: /Includes.rst.txt
.. _feature-99169-1669832578:
===============================================
Feature: #99169 - Add backend user group filter
===============================================
See :issue:`99169`
Description
===========
The :guilabel:`Backend Users` module now offers the possibility to filter for
backend user groups. A new search field allows to filter by arbitrary string or
user group ID.
Impact
======
Administrators in the backend are now able to filter the backend user groups in
the :guilabel:`Backend Users` module.
.. index:: Backend, ext:beuser
@@ -0,0 +1,73 @@
.. include:: /Includes.rst.txt
.. _feature-99194-1669413174:
===========================================================================================
Feature: #99194 - Support for various string comparisons for stdWrap.if TypoScript function
===========================================================================================
See :issue:`99194`
Description
===========
The TypoScript function :typoscript:`if.` now supports several new sub-properties
for comparing a value (provided via :typoscript:`if.value = ...`),
if it contains a certain part of a string, or starts with a certain
part, or ends with a certain part. All of these properties also work with
the :typoscript:`if.negate` flag.
The new TypoScript properties for `if.` are called:
* :typoscript:`if.contains`
* :typoscript:`if.startsWith`
* :typoscript:`if.endsWith`
All of the mentioned properties can be assigned a static value, and support
:typoscript:`stdWrap` as their sub-properties.
Impact
======
As :typoscript:`if.` is available in most content objects, :typoscript:`stdWrap` or
data processors, it can now be used more exhaustive.
Example for :typoscript:`ìf.contains`:
.. code-block:: typoscript
# Add a span tag before the page title if the page title
# contains the string "media"
page.10 = TEXT
page.10.data = page:title
page.10.htmlSpecialChars = 1
page.10.prepend = TEXT
page.10.prepend.value = <span class="icon-video"></span>
page.10.prepend.if.value.data = page:title
page.10.prepend.if.contains = Media
page.10.outerWrap = <h1>|</h1>
Example for :typoscript:`ìf.endsWith`:
.. code-block:: typoscript
# Add a footer note, if the page author ends with "Kott"
page.100 = TEXT
page.100.value = This is an article from Benji
page.100.htmlSpecialChars = 1
page.100.if.value.data = page:author
page.100.if.endsWith = Kott
page.100.wrap = <footer>|</footer>
Example for :typoscript:`ìf.startsWith`:
.. code-block:: typoscript
page.10 = TEXT
page.10.value = Your editor added the magic word in the header field
page.10.htmlSpecialChars = 1
page.10.if.value.data = DB:tt_content:1234:header
page.10.if.startsWith = Bazinga
.. index:: TypoScript, ext:frontend
@@ -0,0 +1,36 @@
.. include:: /Includes.rst.txt
.. _feature-99212-1669896293:
==============================================================
Feature: #99212 - Group select item in FormEngine via TSconfig
==============================================================
See :issue:`99212`
Description
===========
The existing TSconfig feature :typoscript:`TCEFORM.{tablename}.{fieldname}.addItems`
can now be used to add new items into existing select item groups by using the
:typoscript:`.group` sub-property set to the group identifier. This grouping is
usually shown in select fields with groups available.
Impact
======
When using the TSconfig :typoscript:`addItems` feature, the :typoscript:`group`
property can now be used:
Example:
.. code-block:: typoscript
TCEFORM.tt_content.layout.addItems {
new-layout = My new layout
new-layout.icon = icon-identifier
new-layout.group = special
}
.. index:: TSConfig, ext:backend
@@ -0,0 +1,58 @@
.. include:: /Includes.rst.txt
.. _feature-97747-1669740094:
=============================================
Feature: #99221 - Introduce CLI setup command
=============================================
See :issue:`99221`
Description
===========
To be able to automate the setup process for new TYPO3 installations,
a new CLI command `setup` is introduced as an alternative to the existing
GUI based web installer.
Impact
======
You can now use `./bin/typo3 setup` to set up your TYPO3 installation without
needing to run through the web installer.
Example
-------
Interactive / guided setup (questions/answers):
.. code-block:: bash
./bin/typo3 setup
Automated setup:
.. code-block:: bash
TYPO3_DB_DRIVER=mysqli \
TYPO3_DB_USERNAME=db \
TYPO3_DB_PORT=3306 \
TYPO3_DB_HOST=db \
TYPO3_DB_DBNAME=db \
TYPO3_SETUP_ADMIN_EMAIL=admin@example.com \
TYPO3_SETUP_ADMIN_USERNAME=admin \
TYPO3_SETUP_CREATE_SITE="https://your-typo3-site.com/" \
TYPO3_PROJECT_NAME="Automated Setup" \
TYPO3_SERVER_TYPE="apache" \
./bin/typo3 setup --force
.. warning::
Variable `TYPO3_DB_PASSWORD` (option `--password`) can be used to provide a
password for the database and `TYPO3_SETUP_ADMIN_PASSWORD`
(option `--admin-user-password`) for the admin user password.
Using this can be a security risk since the password may end up in shell
history files. Prefer the interactive mode. Additionally, writing a command
to shell history can be suppressed by prefixing the command with a space
when using `bash` or `zsh`.
.. index:: ext:install
@@ -0,0 +1,35 @@
.. include:: /Includes.rst.txt
.. _feature-99226-1669801019:
=========================================================
Feature: #99226 - Introduce dbType json for TCA type user
=========================================================
See :issue:`99226`
.. attention::
This TCA option is **no longer available**! It has been
:ref:`replaced <important-100088-1677950866>` by the dedicated
:ref:`json <feature-100088-1677965005>` TCA type. Do not use
this option in your installation, but use the new TCA type.
Description
===========
To allow storage and usage of JSON data in TCA type `user` without needing to
decode the JSON in each user implementation manually, a dbType is introduced
for TCA type `user`.
Impact
======
When creating TCA type `user` fields with a database JSON field, the
dbType `json` can now be set. After setting the dbType, the form engine will
automatically provide the decoded JSON to the RecordProviders and the `user`
PHP implementation can then use the field value.
.. index:: Backend, PHP-API, ext:backend
@@ -0,0 +1,51 @@
.. include:: /Includes.rst.txt
.. _feature-99234-1669840449:
=========================================================
Feature: #99234 - Dynamic URL parts in TYPO3 backend URLs
=========================================================
See :issue:`99234`
Description
===========
TYPO3's backend URL routing now uses Symfony's routing component for resolving
and generating URLs.
This way, it is possible for extension authors to register backend routes with
path segments that contain dynamic parts, which are then resolved into a request
attribute called "routing".
These routes are defined within the route path as named placeholders.
Impact
======
It is possible to define routes with placeholders in an extension's :file:`Routes.php`:
.. code-block:: php
return [
'my_route' => [
'path' => '/rollback-item/{identifier}',
'target' => \MyVendor\MyPackage\Controller\RollbackController::class . '::handle',
],
];
Within the controller:
.. code-block:: php
public function handle(ServerRequestInterface $request): ResponseInterface
{
$routing = $request->getAttribute('routing');
$myIdentifier = $routing['identifier'];
$route = $routing->getRoute();
// ...
}
.. index:: Backend, PHP-API, ext:backend
@@ -0,0 +1,27 @@
.. include:: /Includes.rst.txt
.. _feature-99245-1669974318:
==============================================================
Feature: #99245 - Registered reactions in configuration module
==============================================================
See :issue:`99245`
Description
===========
With :issue:`98373`, the new reactions component has been introduced to TYPO3
Core. Since reactions allow to hook into the system, it's important for site
administrators to have an overview of registered reactions.
Therefore, the configuration module does now list all registered reactions
with their type identifier and corresponding configuration.
Impact
======
It's now possible for site administrators to get an overview of all registered
reactions in the configuration module.
.. index:: Backend, ext:reactions
@@ -0,0 +1,22 @@
.. include:: /Includes.rst.txt
.. _important-88158-1668433741:
=================================================
Important: #88158 - Replaced moment.js with luxon
=================================================
See :issue:`88158`
Description
===========
The JavaScript library `luxon` is added to TYPO3 as a replacement for `moment.js`
that is `declared legacy`_. All code shipped by TYPO3 is migrated to `luxon`.
Albeit shipped `moment.js` is not considered being public API, it is worth
mentioning that said library is removed with TYPO3 v12.1.
.. _declared legacy: https://momentjs.com/docs/#/-project-status/
.. index:: Backend, JavaScript, NotScanned, ext:core
@@ -0,0 +1,26 @@
.. include:: /Includes.rst.txt
.. _important-98502-1664738430:
=============================================================
Important: #98502 - Correct fallback to default error handler
=============================================================
See :issue:`98502`
Description
===========
The site configuration allows to define the HTTP error status code to be
handled, e.g. by showing the content of a given page.
The backend module states "Make sure to have at least 0 (not defined otherwise)
configured in order to serve helpful error messages to your visitors." but the
fallback to "0" has not been implemented yet until now.
If no error handling for the given HTTP error status code is configured, but
one for "any error not defined otherwise", the latter is used as fallback. This
reduces the configuration effort if only one error handling configuration is
used for all kind of error codes.
.. index:: Frontend, ext:core
@@ -0,0 +1,24 @@
.. include:: /Includes.rst.txt
.. _important-99044-1668077928:
==================================================================================
Important: #99044 - Ensure auto-created redirect are stored on connected site root
==================================================================================
See :issue:`99044`
Description
===========
Long time ago, automatically created redirects were created on the top root page
:php:`pid=0`, which has been changed meanwhile to create them
using the page ID of the changed page as :sql:`pid` with :issue:`91776`.
This led to some issues, like permissions during copying and pasting pages.
Automatically created redirects are now stored using the root page ID of the
site configurations as :sql:`pid` to minimize side-effect issues and prepare
follow-up features.
.. index:: ext:redirects
+54
View File
@@ -0,0 +1,54 @@
:template: changelogOverview.html
.. include:: /Includes.rst.txt
.. _changelog-12-1:
=============
12.1 Changes
=============
**Table of contents**
.. contents::
:local:
:depth: 1
Breaking Changes
================
None since TYPO3 v12.0 release.
.. attention::
After TYPO3 v12.0, only new functionality with a solid migration path
can be added on top, with aiming for as little as possible breaking changes
after the initial v12.0 release on the way to LTS.
Features
========
.. toctree::
:maxdepth: 1
:titlesonly:
:glob:
Feature-*
Deprecation
===========
.. toctree::
:maxdepth: 1
:titlesonly:
:glob:
Deprecation-*
Important
=========
.. toctree::
:maxdepth: 1
:titlesonly:
:glob:
Important-*