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,75 @@
.. include:: /Includes.rst.txt
.. _deprecation-89139:
========================================================================
Deprecation: #89139 - Console Commands configuration format Commands.php
========================================================================
See :issue:`89139`
Description
===========
The console command configuration file format :php:`Configuration/Commands.php`
has been marked as deprecated in favor of the symfony service tag
:yaml:`console.command`. The tag allows to configure dependency injection and
command registration in one single location.
Impact
======
Providing a command configuration in :php:`Configuration/Commands.php` will
trigger a PHP :php:`E_USER_DEPRECATED` error when the respective commands have not already
been defined via symfony service tags.
Extensions that provide both, the deprecated configuration file and service
tags, will not trigger a PHP :php:`E_USER_DEPRECATED` error in order to allow extensions to
support multiple TYPO3 major versions.
Affected Installations
======================
TYPO3 installations with custom extensions that configure symfony console commands
via :php:`Configuration/Commands.php` and have not been migrated to add symfony
service tags.
Migration
=========
Add the :yaml:`console.command` tag to command classes. Use the tag attribute :yaml:`command`
to specify the command name. The optional tag attribute :yaml:`schedulable` may be set
to false to exclude the command from the TYPO3 scheduler.
.. code-block:: yaml
services:
_defaults:
autowire: true
autoconfigure: true
public: false
MyVendor\MyExt\Command\FooCommand:
tags:
- name: 'console.command'
command: 'my:command'
schedulable: false
Command aliases are to be configured as separate tags.
The optional tag attribute :yaml:`alias` should be set to true for alias commands.
.. code-block:: yaml
MyVendor\MyExt\Command\BarCommand:
tags:
- name: 'console.command'
command: 'my:bar'
- name: 'console.command'
command: 'my:old-bar-command'
alias: true
schedulable: false
.. index:: CLI, PHP-API, PartiallyScanned, ext:core
@@ -0,0 +1,110 @@
.. include:: /Includes.rst.txt
.. _deprecation-89463:
===================================================
Deprecation: #89463 - Switchable Controller Actions
===================================================
See :issue:`89463`
Description
===========
Switchable controller actions have been marked as deprecated and will be removed
in TYPO3 version 12.0.
Switchable controller actions are used to override the allowed set of controllers and actions via TypoScript or plugin
flexforms. While this is convenient for reusing the same plugin for a lot of different use cases, it's also very
problematic as it completely overrides the original configuration defined via
:php:`\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin`.
Switchable controller actions therefore have bad implications that rectify their removal.
First of all, switchable controller actions override the original configuration of plugins at runtime and possibly
depending on conditions which contradicts the idea of :php:`\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin`
being the authoritative way to define configuration.
Using the same plugin as an entry point for many different functionalities contradicts the idea of a plugin serving one
specific purpose. Switchable controller actions allow for creating one central plugin that takes care of everything.
Impact
======
All plugins that are using switchable controller actions need to be split into multiple different plugins. Usually, one
would create a new plugin for each possible switchable controller actions configuration entry.
Affected Installations
======================
All installations that make use of switchable controller actions, either via flexform configuration of plugins or via
TypoScript configuration.
Migration
=========
Unfortunately, an automatic migration is not possible. As switchable controller actions allowed to override the whole
configuration of allowed controllers and actions, the only way to migrate is to create dedicated plugins for each former
switchable controller actions configuration entry.
Example:
.. code-block:: xml
<switchableControllerActions>
<TCEforms>
<label>switchable controller actions</label>
<config>
<renderType>selectSingle</renderType>
<items>
<numIndex index="1">
<numIndex index="0">List</numIndex>
<numIndex index="1">Product->list</numIndex>
</numIndex>
<numIndex index="2">
<numIndex index="0">Show</numIndex>
<numIndex index="1">Product->show</numIndex>
</numIndex>
</items>
</config>
</TCEforms>
</switchableControllerActions>
This configuration would lead to the creation configuration of two different plugins like this:
.. code-block:: php
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'extension',
'list',
[
'Product' => 'list'
]
);
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'extension',
'show',
[
'Product' => 'show'
]
);
Advantages of Separate Plugins
------------------------------
When using separate plugins for each switchable controller action combination,
it is possible to properly define which action should be cached.
In addition, TYPO3 v10 LTS allows to group plugins in FormEngine directly
to semantically register various plugins in one specific group.
See :ref:`changelog-Feature-91008-ItemGroupingForTCASelectItems`
for more details.
.. index:: FlexForm, PHP-API, TypoScript, NotScanned, ext:extbase
@@ -0,0 +1,47 @@
.. include:: /Includes.rst.txt
.. _deprecation-89673:
==========================================================
Deprecation: #89673 - Extbase's WebRequest and WebResponse
==========================================================
See :issue:`89673`
Description
===========
Both classes :php:`\TYPO3\CMS\Extbase\Mvc\Web\Request` and :php:`\TYPO3\CMS\Extbase\Mvc\Web\Response`
have been marked as deprecated. Along with their deprecation, all relevant logic has been moved into their parent
classes :php:`\TYPO3\CMS\Extbase\Mvc\Request` and :php:`\TYPO3\CMS\Extbase\Mvc\Response`.
This is done to simplify the request/response handling of Extbase and to ease the transition towards
a PSR-7 compatible handling.
Impact
======
There is no impact yet as the "web" versions of the request and response are still used by Extbase.
The only thing that is worth mentioning is that those who implement custom requests and/or responses
should derive from the non "web" versions now.
Affected Installations
======================
All installations that implement custom request/response objects that derive from
:php:`\TYPO3\CMS\Extbase\Mvc\Web\Request` and :php:`\TYPO3\CMS\Extbase\Mvc\Web\Response`.
Those who don't change the request/response handling, will not realize this change.
Migration
=========
All installations that implement custom request/response objects that derive from
:php:`\TYPO3\CMS\Extbase\Mvc\Web\Request` and :php:`\TYPO3\CMS\Extbase\Mvc\Web\Response` should now
derive from :php:`\TYPO3\CMS\Extbase\Mvc\Request` (and override the :php:`$format` property) and
:php:`\TYPO3\CMS\Extbase\Mvc\Response` (and override the :php:`shutdown` method).
.. index:: PHP-API, NotScanned, ext:extbase
@@ -0,0 +1,55 @@
.. include:: /Includes.rst.txt
.. _deprecation-89866:
================================================================
Deprecation: #89866 - Global TYPO3-information related constants
================================================================
See :issue:`89866`
Description
===========
The following global constants, which are initialized at the very
beginning of each TYPO3-related PHP process, have been marked as deprecated:
* :php:`TYPO3_copyright_year`
* :php:`TYPO3_URL_GENERAL`
* :php:`TYPO3_URL_LICENSE`
* :php:`TYPO3_URL_EXCEPTION`
* :php:`TYPO3_URL_DONATE`
* :php:`TYPO3_URL_WIKI_OPCODECACHE`
They have been migrated to the PHP class :php:`TYPO3\CMS\Core\Information\Typo3Information`
in order to benefit from opcaching, and to exactly reference when they are used
and where they are used throughout TYPO3.
This allows for further optimizations during the Bootstrap process and in our
testing suites.
In addition, the new PHP class encapsulates all global TYPO3-information and
community-wide information in one place.
Impact
======
No :php:`E_USER_DEPRECATED` error is triggered, however the constants will work during
TYPO3 v10, and be removed with TYPO3 v11.
Affected Installations
======================
Any TYPO3 installation with a custom extension that uses these
constants directly, which is highly unlikely.
Migration
=========
Use the public class constants or the public methods of the
new PHP class :php:`TYPO3\CMS\Core\Information\Typo3Information` directly.
.. index:: PHP-API, FullyScanned, ext:core
@@ -0,0 +1,63 @@
.. include:: /Includes.rst.txt
.. _deprecation-89868:
===============================================================
Deprecation: #89868 - Remove reqCHash functionality for plugins
===============================================================
See :issue:`89868`
Description
===========
Extbase and pi-based plugins that are non-cacheable could previously
require the validation of the cHash GET parameter
in order to validate GET parameters against the "cHash".
In Extbase plugins, this could be configured via a TypoScript feature toggle (enabled by default):
:typoscript:`config.tx_extbase.features.requireCHashArgumentForActionArguments = 1`
In Pi-based plugins the public property :php:`AbstractPlugin->pi_checkCHash`
was used to enable the cHash validation for non-cacheable plugins.
Both plugin systems triggered the method :php:`TypoScriptFrontendController->reqCHash` which
validated relevant GET parameters. However, the :php:`PageArgumentValidator` PSR-15 middleware now
always validates the cHash, so a plugin does not need to know about cHash validation anymore and
therefore does not need to set the option.
This means the options are not needed anymore, as the validation already happens during the Frontend
request handling process. The options are removed.
In addition, the method :php:`TypoScriptFrontendController->reqCHash()` has been marked as deprecated and
is not in use anymore.
Impact
======
Setting the option in Extbase or Pi-Base has no effect anymore.
Calling the PHP method :php:`TypoScriptFrontendController->reqCHash()`
will trigger a PHP :php:`E_USER_DEPRECATED` error.
Internal classes such as the :php:`CacheHashEnforcer` are removed.
Affected Installations
======================
TYPO3 installations with plugins, where one of the options is set,
or where the PHP method is called directly.
Migration
=========
Remove the options / flags as they have no effect in TYPO3 v10 anymore.
Calling the method directly is also not needed, as the PageArgumentValidator is executing this
validation now at every request.
.. index:: Frontend, PartiallyScanned, ext:frontend
@@ -0,0 +1,60 @@
.. include:: /Includes.rst.txt
.. _deprecation-89870:
===================================================================
Deprecation: #89870 - New PSR-14 Events for Extbase-related signals
===================================================================
See :issue:`89870`
Description
===========
The following signals have been marked as deprecated in favor of new PSR-14 events:
- :php:`TYPO3\CMS\Extbase\Mvc\Dispatcher::afterRequestDispatch`
- :php:`TYPO3\CMS\Extbase\Mvc\Controller\ActionController::beforeCallActionMethod`
- :php:`TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::afterMappingSingleRow`
- :php:`TYPO3\CMS\Extbase\Persistence\Generic\Backend::beforeGettingObjectData`
- :php:`TYPO3\CMS\Extbase\Persistence\Generic\Backend::afterGettingObjectData`
- :php:`TYPO3\CMS\Extbase\Persistence\Generic\Backend::endInsertObject`
- :php:`TYPO3\CMS\Extbase\Persistence\Generic\Backend::afterUpdateObject`
- :php:`TYPO3\CMS\Extbase\Persistence\Generic\Backend::afterPersistObject`
- :php:`TYPO3\CMS\Extbase\Persistence\Generic\Backend::afterRemoveObject`
The method :php:`emitBeforeCallActionMethodSignal` in :php:`ActionController`
has been marked as deprecated and is not called by Extbase itself anymore.
Impact
======
Using any of the signals will still work as expected, but will trigger
a PHP :php:`E_USER_DEPRECATED` error.
Calling the method :php:`emitBeforeCallActionMethodSignal` will trigger a
PHP :php:`E_USER_DEPRECATED` error.
Affected Installations
======================
TYPO3 installations with extensions using the Extbase framework and
Extbase-internal hooks.
Migration
=========
The following new PSR-14-based Events should be used instead:
- :php:`TYPO3\CMS\Extbase\Event\Mvc\AfterRequestDispatchedEvent`
- :php:`TYPO3\CMS\Extbase\Event\Mvc\BeforeActionCallEvent`
- :php:`TYPO3\CMS\Extbase\Event\Persistence\AfterObjectThawedEvent`
- :php:`TYPO3\CMS\Extbase\Event\Persistence\ModifyQueryBeforeFetchingObjectDataEvent`
- :php:`TYPO3\CMS\Extbase\Event\Persistence\ModifyResultAfterFetchingObjectDataEvent`
- :php:`TYPO3\CMS\Extbase\Event\Persistence\EntityAddedToPersistenceEvent`
- :php:`TYPO3\CMS\Extbase\Event\Persistence\EntityUpdatedInPersistenceEvent`
- :php:`TYPO3\CMS\Extbase\Event\Persistence\EntityRemovedFromPersistenceEvent`
- :php:`TYPO3\CMS\Extbase\Event\Persistence\EntityPersistedEvent`
.. index:: PHP-API, PartiallyScanned, ext:extbase
@@ -0,0 +1,45 @@
.. include:: /Includes.rst.txt
.. _deprecation-90007:
=====================================================================
Deprecation: #90007 - Global constants TYPO3_version and TYPO3_branch
=====================================================================
See :issue:`90007`
Description
===========
Two of the most "stable" global constants in the TYPO3 Core - :php:`TYPO3_version` and :php:`TYPO3_branch` have been marked as deprecated.
The change was mainly driven by the necessity to minimize runtime-generated constants in order to optimize performance, also for op-caching.
The same information is available in a new PHP class :php:`TYPO3\CMS\Core\Information\Typo3Version`, which also defines
the constants for backwards-compatibility reasons.
Impact
======
No PHP :php:`E_USER_DEPRECATED` error is triggered, however the constants will work during
TYPO3 v10 and TYPO3 v11, but will be removed with TYPO3 v12.
Affected Installations
======================
TYPO3 installations with custom extensions accessing the constants,
which is common for having extension support for multiple TYPO3 versions.
Migration
=========
It is highly recommended to use the :php:`Typo3Version` class instead of
the constants, as they will be removed in a future TYPO3 version.
Check the Extension Scanner in the Upgrade section of TYPO3 to see
if any extensions you use might be affected.
.. index:: PHP-API, FullyScanned, ext:core
@@ -0,0 +1,47 @@
.. include:: /Includes.rst.txt
.. _deprecation-90019:
==========================================================
Deprecation: #90019 - Page permission logic by DataHandler
==========================================================
See :issue:`90019`
Description
===========
A new :php:`PagePermissionAssembler` class builds the page permissions, allowing to thin out certain parts of :php:`DataHandlers` responsibilities.
The following properties and methods within :php:`DataHandler` have been marked as deprecated:
* :php:`TYPO3\CMS\Core\DataHandling\DataHandler->defaultPermissions`
* :php:`TYPO3\CMS\Core\DataHandling\DataHandler->pMap`
* :php:`TYPO3\CMS\Core\DataHandling\DataHandler->setTSconfigPermissions()`
* :php:`TYPO3\CMS\Core\DataHandling\DataHandler->assemblePermissions()`
The following methods should only be called with integers as permission argument:
* :php:`TYPO3\CMS\Core\DataHandling\DataHandler->doesRecordExist()`
* :php:`TYPO3\CMS\Core\DataHandling\DataHandler->recordInfoWithPermissionCheck()`
Impact
======
Calling the mentioned methods will trigger a PHP :php:`E_USER_DEPRECATED` error and will be removed in TYPO3 v11.0.
Affected Installations
======================
Any TYPO3 installation that enriches page permission handling and directly accesses the methods or properties in :php:`DataHandler`.
Migration
=========
Ensure to use the new :php:`PagePermissionAssembler` PHP class
which serves as a proper API for creating page permissions.
.. index:: PHP-API, PartiallyScanned, ext:core
@@ -0,0 +1,53 @@
.. include:: /Includes.rst.txt
.. _deprecation-90249:
============================================================================
Deprecation: #90249 - Package related Signal Slots migrated to PSR-14 events
============================================================================
See :issue:`90249`
Description
===========
The following Signal Slots have been replaced by new PSR-14 events
which can be used as 1:1 equivalents:
* :php:`PackageManagement::packagesMayHaveChanged`
* :php:`TYPO3\CMS\Extensionmanager\Utility\InstallUtility::afterExtensionInstall`
* :php:`TYPO3\CMS\Extensionmanager\Utility\InstallUtility::afterExtensionUninstall`
* :php:`TYPO3\CMS\Extensionmanager\Utility\InstallUtility::afterExtensionT3DImport`
* :php:`TYPO3\CMS\Extensionmanager\Utility\InstallUtility::afterExtensionStaticSqlImport`
* :php:`TYPO3\CMS\Extensionmanager\Utility\InstallUtility::afterExtensionFileImport`
* :php:`TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService::willInstallExtensions`
* :php:`TYPO3\CMS\Extensionmanager\ViewHelper\ProcessAvailableActionsViewHelper::processActions`
Impact
======
Using the mentioned signals will trigger a PHP :php:`E_USER_DEPRECATED` error.
Affected Installations
======================
TYPO3 installations with custom extensions using these signals.
Migration
=========
Use the new PSR-14 alternatives:
* :php:`TYPO3\CMS\Core\Package\Event\PackagesMayHaveChangedEvent`
* :php:`TYPO3\CMS\Core\Package\Event\AfterPackageActivationEvent`
* :php:`TYPO3\CMS\Core\Package\Event\AfterPackageDeactivationEvent`
* :php:`TYPO3\CMS\Core\Package\Event\BeforePackageActivationEvent`
* :php:`TYPO3\CMS\Extensionmanager\Event\AfterExtensionDatabaseContentHasBeenImportedEvent`
* :php:`TYPO3\CMS\Extensionmanager\Event\AfterExtensionStaticDatabaseContentHasBeenImportedEvent`
* :php:`TYPO3\CMS\Extensionmanager\Event\AfterExtensionFilesHaveBeenImportedEvent`
* :php:`TYPO3\CMS\Extensionmanager\Event\AvailableActionsForExtensionEvent`
.. index:: PHP-API, FullyScanned, ext:core
@@ -0,0 +1,51 @@
.. include:: /Includes.rst.txt
.. _deprecation-90258:
===============================================
Deprecation: #90258 - Simplified RTE Parser API
===============================================
See :issue:`90258`
Description
===========
The PHP class :php:`RteHtmlParser` which is used to transform RTE-based
textarea fields from the database to the configured Rich Text Editor, and back, has a new simplified API.
For this reason, the following two methods have been marked as deprecated:
* :php:`TYPO3\CMS\Core\Html\RteHtmlParser->init()`
* :php:`TYPO3\CMS\Core\Html\RteHtmlParser->RTE_transform()`
Impact
======
Calling any of the methods will trigger a PHP :php:`E_USER_DEPRECATED` error.
Affected Installations
======================
TYPO3 installations with extensions dealing with extracting or adding content such as "l10nmgr", or any custom extension using
the methods.
Migration
=========
The method :php:`TYPO3\CMS\Core\Html\RteHtmlParser->init()` can be removed without substitution, as it
serves no purpose anymore.
The method :php:`TYPO3\CMS\Core\Html\RteHtmlParser->RTE_transform()` now has two methods as substitute,
depending on the direction which is necessary. This was previously
done in the third method argument ("rte" and "db"):
- :php:`transformTextForRichTextEditor($content, $configuration)`
- :php:`transformTextForPersistence($content, $configuration)`
The second argument :php:`$configuration` is now the `processing` configuration (`proc`) of the RTE configuration.
.. index:: RTE, FullyScanned, ext:core
@@ -0,0 +1,44 @@
.. include:: /Includes.rst.txt
.. _deprecation-90260:
=================================================================
Deprecation: #90260 - ResourceFactory::getInstance pseudo-factory
=================================================================
See :issue:`90260`
Description
===========
The method :php:`ResourceFactory::getInstance()` acts as a wrapper
for the constructor which originally was meant as a performance
improvement as pseudo-singleton concept in TYPO3 v4.7.
However, :php:`ResourceFactory` was never optimized and now with Dependency
Injection, :php:`ResourceFactory` can be used directly.
Therefore the method has been marked as deprecated.
Impact
======
Calling :php:`ResourceFactory::getInstance()` will trigger a PHP :php:`E_USER_DEPRECATED` error.
Affected Installations
======================
Any TYPO3 installation with custom PHP code calling the method.
Migration
=========
Check TYPO3's "Extension Scanner" in the Install Tool if you're affected and replace with constructor injection via Dependency
Injection if possible, or use :php:`GeneralUtility::makeInstance(ResourceFactory::class)` instead.
The latter can already applied in earlier versions (TYPO3 v7 or higher) to ease optimal migration of this deprecation.
.. index:: FAL, PHP-API, FullyScanned, ext:core
@@ -0,0 +1,42 @@
.. include:: /Includes.rst.txt
.. _deprecation-90348:
==========================================
Deprecation: #90348 - PageLayoutView class
==========================================
See :issue:`90348`
Description
===========
The :php:`PageLayoutView` class, which is considered internal API, has been marked as deprecated in favor
of the new Fluid-based alternative which renders the "page" BE module.
Impact
======
Implementations which depend on :php:`PageLayoutView` should prepare to use the alternative implementation (by overlaying and overriding Fluid templates of EXT:backend).
Affected Installations
======================
* Any site which overrides the :php:`PageLayoutView` class. The overridden class will
still be instantiated when rendering previews in BE page module - but no methods
will be called on the instance **unless** they are called by a third party hook subscriber.
* Any site which depends on PSR-14 events associated with :php:`PageLayoutView` will only
have those events dispatched if the :php:`fluidBasedPageModule` feature flag is :php:`false`.
* Affects :php:`\TYPO3\CMS\Backend\View\Event\AfterSectionMarkupGeneratedEvent`.
* Affects :php:`\TYPO3\CMS\Backend\View\Event\BeforeSectionMarkupGeneratedEvent`.
Migration
=========
Fluid templates can be extended or replaced to render custom header, footer or preview of
a given :typoscript:`CType`, see feature description for feature :issue:`90348`.
.. index:: Backend, Fluid, NotScanned, ext:backend
@@ -0,0 +1,34 @@
.. include:: /Includes.rst.txt
.. _deprecation-90390:
=====================================================================================
Deprecation: #90390 - BrokenLinkRepository::getNumberOfBrokenLinks() in linkvalidator
=====================================================================================
See :issue:`90390`
Description
===========
The method :php:`BrokenLinkRepository::getNumberOfBrokenLinks()` has been marked as deprecated.
Impact
======
Usage of the method triggers a PHP :php:`E_USER_DEPRECATED` error.
Affected Installations
======================
Every TYPO3 installation that uses the method.
Migration
=========
Use :php:`BrokenLinkRepository::isLinkTargetBrokenLink()` instead.
.. index:: Backend, NotScanned, ext:linkvalidator
@@ -0,0 +1,51 @@
.. include:: /Includes.rst.txt
.. _deprecation-90421:
======================================
Deprecation: #90421 - DocumentTemplate
======================================
See :issue:`90421`
Description
===========
The PHP class :php:`TYPO3\CMS\Backend\Template\DocumentTemplate`,
also available as :php:`$GLOBALS['TBE_TEMPLATE']` until TYPO3 v10.0
served as a basis to render backend modules or HTML-based output
in TYPO3 Backend.
Since TYPO3 v7, the new API via php:`ModuleTemplate` can be used instead. The :php:`DocumentTemplate` class has been marked as deprecated.
Impact
======
Instantiating the :php:`DocumentTemplate` class will trigger a PHP :php:`E_USER_DEPRECATED` error.
Affected Installations
======================
TYPO3 installations with third-party extensions adding backend modules using the DocumentTemplate API.
These can typically be identified by extensions that "worked" but somehow looked ugly since TYPO3 v7 due to CSS and HTML changes.
Migration
=========
Use ModuleTemplate API instead, which can be built like this in a typical non-Extbase Backend controller (e.g. in an action such as "overviewAction"):
.. code-block:: php
$moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
$content = $this->getHtmlContentFromMyModule();
$moduleTemplate->setTitle('My module');
$moduleTemplate->setContent($content);
return $this->responseFactory->createResponse()
->withHeader('Content-Type', 'text/html; charset=utf-8')
->withBody($this->streamFactory->createStream($moduleTemplate->renderContent()));
.. index:: Backend, PHP-API, FullyScanned, ext:backend
@@ -0,0 +1,37 @@
.. include:: /Includes.rst.txt
.. _deprecation-90522:
======================================================
Deprecation: #90522 - TSFE properties regarding images
======================================================
See :issue:`90522`
Description
===========
The image related properties :php:`$imagesOnPage` and :php:`$lastImageInfo` of
:php:`TypoScriptFrontendController` have been marked as deprecated.
Impact
======
Calling these properties will trigger a PHP :php:`E_USER_DEPRECATED` error.
Affected Installations
======================
All installations using these properties are affected.
Migration
=========
For :php:`$imagesOnPage` the AssetCollector may be used instead:
.. code-block:: php
$assetCollector = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(TYPO3\CMS\Core\Page\AssetCollector::class);
$imagesOnPage = $assetCollector->getMedia();
.. index:: Frontend, PHP-API, NotScanned, ext:core
@@ -0,0 +1,40 @@
.. include:: /Includes.rst.txt
.. _feature-78347:
==========================================================
Feature: #78347 - Add StdWrap properties to FilesProcessor
==========================================================
See :issue:`78347`
Description
===========
StdWrap properties have been added to FLUIDTEMPLATEs FilesProcessor the same way as in FilesContentObject.
That way you can implement slide-functionality on rootline for file resources.
TypoScript dataProcessing example with FilesProcessor
-----------------------------------------------------
.. code-block:: typoscript
page.10 = FLUIDTEMPLATE
page.10.dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\FilesProcessor
10 {
references.data = levelmedia: -1, slide
as = myfiles
}
Impact
======
The FilesProcessor can slide up and down the rootline to collect images for FLUID templates.
One usual feature is to use images attached to pages and use them up and down the page tree
for header images in frontend.
.. index:: TypoScript, Frontend
@@ -0,0 +1,147 @@
.. include:: /Includes.rst.txt
.. _feature-78450:
===================================================
Feature: #78450 - Introduce PreviewRenderer pattern
===================================================
See :issue:`78450`
Pre-requisites
==============
The :php:`PreviewRenderer` usage is only active if the "fluid based page layout module" feature is enabled. This feature
is activated by default in TYPO3 versions 10.3 and later.
The feature toggle can be located in the `Settings` admin module under `Feature Toggles`. Or it can be set in
PHP using :php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['fluidBasedPageModule'] = true;`.
Description
===========
A new pattern has been introduced to facilitate (record) previews in TYPO3. A default implementation has been
added which provides support for the previous methods of generating previews (content previews - using hooks
or by defining a Fluid template to render).
The new pattern creates a strict contract for code which generates such previews and enables switching out the
implementation of both the resolving logic (which finds a preview renderer for a given table and record) as well
as the rendering logic (which now renders both the actual preview and has contract methods for adding wrapping).
The main differences between the old and the new approach are:
* The class used to render previews is now defined in :php:`TCA` and can be defined per-type or for any type.
* The resolver used to find preview renderers is a global implementation overridable in configuration.
* A single preview renderer will now be used. Before, hook subscribers had to toggle passed-by-reference flags.
* Wrapping is no longer forced to be a :html:`<span>` tag so you are not restricted to inline and inline-block display.
* Preview renderers have a public contract which splits up actual preview and wrapping, allowing third party renderers
to subclass the original renderer and for example only change the wrapping tag.
* Preview rendering can now be done ad-hoc. The pattern can be used from any context where the old pattern
could only be used (was only used) in the :php:`PageLayoutView` for content previews.
Impact
======
The feature adds two new concepts:
* :php:`PreviewRendererResolver` which is a global implementation to detect which :php:`PreviewRenderer` a given record needs.
* :php:`PreviewRenderer` which is the class responsible for generating the preview and the wrapping.
Configuring the implementation
------------------------------
Individual preview renderers can be defined by using one of the following two approaches:
.. code-block:: php
$GLOBALS['TCA'][$table]['ctrl']['previewRenderer'] = My\PreviewRenderer::class;
This specifies the PreviewRenderer to be used for any record in :php:`$table`.
Or if your table has a "type" field/attribute:
.. code-block:: php
$GLOBALS['TCA'][$table]['types'][$type]['previewRenderer'] = My\PreviewRenderer::class;
This specifies the PreviewRenderer only for records of type :php:`$type` as determined by the type field of your table.
Or finally, if your table and field have a :php:`subtype_value_field` TCA setting (like :php:`tt_content.list_type` for example)
and you want to register a preview renderer that applies only when that value is selected (e.g. when a certain plugin type
is selected and you can't match it with the "type" of the record alone):
.. code-block:: php
$GLOBALS['TCA'][$table]['types'][$type]['previewRenderer'][$subType] = My\PreviewRenderer::class;
Where :php:`$type` is for example :php:`list` (indicating a plugin) and :php:`$subType` is the value of the :php:`list_type` field when the
type of plugin you want to target is selected as plugin type.
.. note::
The recommended location is in the :php:`ctrl` array in your extension's :file:`Configuration/TCA/$table.php` or
:file:`Configuration/TCA/Overrides/$table.php` file. The former is used when your extension is the one that creates the table,
the latter is used when you need to override TCA properties of tables added by the core or other extensions.
The PreviewRenderer interface
-----------------------------
:php:`\TYPO3\CMS\Backend\Preview\PreviewRendererInterface` must be implemented by any :php:`PreviewRenderer` and contains some
API methods:
.. code-block:: php
/**
* Dedicated method for rendering preview header HTML for
* the page module only. Receives $item which is an instance of
* GridColumnItem which has a getter method to return the record.
*
* @param GridColumnItem
* @return string
*/
public function renderPageModulePreviewHeader(GridColumnItem $item);
/**
* Dedicated method for rendering preview body HTML for
* the page module only.
*
* @param GridColumnItem $item
* @return string
*/
public function renderPageModulePreviewContent(GridColumnItem $item);
/**
* Render a footer for the record to display in page module below
* the body of the item's preview.
*
* @param GridColumnItem $item
* @return string
*/
public function renderPageModulePreviewFooter(GridColumnItem $item): string;
/**
* Dedicated method for wrapping a preview header and body HTML.
*
* @param string $previewHeader
* @param string $previewContent
* @param GridColumnItem $item
* @return string
*/
public function wrapPageModulePreview($previewHeader, $previewContent, GridColumnItem $item);
Further methods are expected to be added to support generic preview rendering, e.g. usages outside PageLayoutView.
Implementing these methods allows you to control the exact composition of the preview.
This means assuming your :php:`PreviewRenderer` returns :html:`<h4>Header</h4>` from the header render method and :html:`<p>Body</p>` from
the preview content rendering method and your wrapping method does :php:`return '<div>' . $previewHeader . $previewContent . '</div>';` then the
entire output becomes :html:`<div><h4>Header</h4><p>Body</p></div>` when combined.
Should you wish to reuse parts of the default preview rendering and only change, for example, the method that renders
the preview body content, you can subclass :php:`\TYPO3\CMS\Backend\Preview\StandardContentPreviewRenderer` in your
own :php:`PreviewRenderer` class - and selectively override the methods from the API displayed above.
.. index:: Backend, TCA
@@ -0,0 +1,24 @@
.. include:: /Includes.rst.txt
.. _feature-79310:
==============================================================
Feature: #79310 - Add options and clipboard to filelist search
==============================================================
See :issue:`79310`
Description
===========
The filelist backend module now shows the clipboard and the display options
checkboxes on search results.
Impact
======
Files and folders can now be put on the clipboard when using the search result
view of the filelist backend module.
.. index:: Backend, ext:filelist
@@ -0,0 +1,24 @@
.. include:: /Includes.rst.txt
.. _feature-82062:
============================================================
Feature: #82062 - Progress for Reference Index update on CLI
============================================================
See :issue:`82062`
Description
===========
The Reference Index updating process now shows the current status
when looping over each database table, to have a more visualized
status.
Impact
======
Calling `./typo3/sysext/core/bin/typo3 referenceindex:update -c` shows the new output when running the reference update (`-c` is for checking only).
.. index:: CLI, ext:lowlevel
@@ -0,0 +1,44 @@
.. include:: /Includes.rst.txt
.. _feature-83847:
=============================================================================
Feature: #83847 - Remove repaired links from Linkvalidator list after editing
=============================================================================
See :issue:`83847`
Description
===========
In the list of broken links provided by Linkvalidator, it is possible to click
on the edit icon for a broken link in order to edit the record directly.
If the record was edited, the list of broken links may no longer be up to date.
There are now 2 possibilities, depending on how :php:`actionAfterEditRecord`
is configured:
recheck (default):
The field is rechecked. (Warning: an RTE field may contain a number
of links, rechecking may lead to delays.)
setNeedsRecheck:
The entries in the list are marked as needing a recheck
Prior to this feature, fixed broken links were not removed from the list, which made fixing
several links at a time confusing and tedious because you either had to
remember which links were already fixed or switch back and forth between
the *Report* and the *Check Links* tab to recheck for broken links.
Impact
======
This feature improves the workflow of fixing broken links.
If the recheck option is selected, this may lead to some delays when
rechecking for broken links, especially if external links are involved.
.. index:: Backend, ext:linkvalidator
@@ -0,0 +1,45 @@
.. include:: /Includes.rst.txt
.. _feature-84214:
====================================================================
Feature: #84214 - Add check if fields are editable for Linkvalidator
====================================================================
See :issue:`84214`
Description
===========
Broken links should only be shown in the list of broken links,
if current backend user has edit access to the field. This way
the editor will no longer get an error message on trying to
edit records he has no permission to edit.
Whether the editor has access depends on a number of factors.
We check the following:
* The current permissions of the page. For editing the page, the editor must have
Permission::PAGE_EDIT, for editing content Permission::CONTENT_EDIT must be available.
* The user has write access to the table. We check if the table
is in 'tables_modify' for the group(s).
* The user has write access to the field. We check if the field
is an exclude field. If yes, it must be included in
'non_exclude_fields' for the group(s).
* The user has write permission for the language of the record.
* For tt_content: The CType is in list of explicitly allowed
values for authMode.
Impact
======
* Broken links for fields that are not editable for the current backend
user will no longer be shown.
* Fields were added to the :sql:`tx_linkvalidator_link` table. "Analyze
Database Structure" must be executed.
* After an update to the new version, checking of broken links should
be reinitialized for the entire site. Until this is done, some broken
links may not be displayed for editors in the broken link report.
.. index:: Backend, ext:linkvalidator
@@ -0,0 +1,73 @@
.. include:: /Includes.rst.txt
.. _feature-86614:
==========================================================================
Feature: #86614 - Add PSR-14 event to control hreflang tags to be rendered
==========================================================================
See :issue:`86614`
Description
===========
It is now possible to alter the hreflang tags just before they
get rendered. You can do this by registering an event listener for
the event :php:`TYPO3\CMS\Frontend\Event\ModifyHrefLangTagsEvent`.
Also the class :php:`TYPO3\CMS\Seo\HrefLang\HrefLangGenerator` has been
refactored to be a listener (identifier :php:`'typo3-seo/hreflangGenerator'`)
to the newly introduced event. This way the system extension seo still
provides hreflang tags but it is now possible to simply register
after or instead of the implementation.
Example
=======
An example implementation could look like this:
:file:`EXT:my_extension/Configuration/Services.yaml`
.. code-block:: yaml
services:
Vendor\MyExtension\HrefLang\EventListener\OwnHrefLang:
tags:
- name: event.listener
identifier: 'my-ext/ownHrefLang'
after: 'typo3-seo/hreflangGenerator'
event: TYPO3\CMS\Frontend\Event\ModifyHrefLangTagsEvent
With :yaml:`after` and :yaml:`before`, you can make sure your own listener is
executed after or before the given identifiers.
:file:`EXT:my_extension/Classes/HrefLang/EventListener/OwnHrefLang.php`
.. code-block:: php
namespace Vendor\MyExtension\HrefLang\EventListener;
use TYPO3\CMS\Frontend\Event\ModifyHrefLangTagsEvent;
class OwnHrefLang
{
public function __invoke(ModifyHrefLangTagsEvent $event): void
{
$hrefLangs = $event->getHrefLangs();
$request = $event->getRequest();
// Do anything you want with $hrefLangs
$hrefLangs = [
'en-US' => 'https://example.com',
'nl-NL' => 'https://example.com/nl'
];
// Override all hrefLang tags
$event->setHrefLangs($hrefLangs);
// Or add a single hrefLang tag
$event->addHrefLang('de-DE', 'https://example.com/de');
}
}
.. index:: ext:seo, PHP-API
@@ -0,0 +1,73 @@
.. include:: /Includes.rst.txt
.. _feature-87072:
=========================================================
Feature: #87072 - Added Configuration Options for Locking
=========================================================
See :issue:`87072`
Description
===========
With change `Feature: #47712 - New Locking API
<https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/7.2/Feature-47712-NewLockingAPI.html>`__ a new Locking API was introduced.
This API can be extended. It provides three locking strategies and an interface for adding your own locking strategy in an extension.
However, until now, the default behaviour could not be changed using only the TYPO3 core.
The introduction of new options makes some of the default properties of the locking API configurable:
* The priority of each locking strategy can be changed.
* The directory where the lock files are written can be configured.
Configuration example
---------------------
:file:`typo3conf/AdditionalConfiguration.php`:
.. code-block:: php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['locking']['strategies'][\TYPO3\CMS\Core\Locking\FileLockStrategy::class]['priority'] = 10;
// The directory specified here must exist und must be a subdirectory of `Environment::getProjectPath()`
$GLOBALS['TYPO3_CONF_VARS']['SYS']['locking']['strategies'][\TYPO3\CMS\Core\Locking\FileLockStrategy::class]['lockFileDir'] = 'mylockdir';
This sets the priority of FileLockStrategy to 10, thus making it the locking strategy with the lowest priority, which
will be chosen last by the LockFactory.
The directory for storing the locks is changed to :file:`mylockdir`.
Impact
======
For administrators
------------------
Nothing changes by default. The default values are used for the Locking API, same as before this change.
If :file:`AdditionalConfiguration.php` is used to change Global Configuration settings for Locking API, and not used with care,
it can seriously compromise the stability of the system. As usual, when overriding Global Configuration with
:file:`LocalConfiguration.php` or :file:`AdditionalConfiguration.php`, great caution must be exercised.
Specifically, do the following:
* Test this on a test system first
* If you change the priorities, make sure your system fully supports the locking strategy which will be chosen by default.
* If you change the directory, make sure the directory exists and will always exist in the future.
For developers
--------------
If a locking strategy is added by an extension, the priority and possibly directory for storing locks should be made
configurable as well.
.. code-block:: php
public static function getPriority()
{
return $GLOBALS['TYPO3_CONF_VARS']['SYS']['locking']['strategies'][self::class]['priority']
?? self::DEFAULT_PRIORITY;
}
.. index:: ext:core
@@ -0,0 +1,35 @@
.. include:: /Includes.rst.txt
.. _feature-87451:
=====================================================================
Feature: #87451 - scheduler:run command accepts multiple task options
=====================================================================
See :issue:`87451`
Description
===========
The `scheduler:run` command now accepts multiple `--task` options.
The tasks will be executed in the order in which they are given:
.. code-block:: bash
./typo3/sysext/core/bin/typo3 scheduler:run --task 1 --task 2
It is now also possible to pass verbose flags to the command to get more information about what is
going on.
A single `-v` flag will output errors only. Two `-vv` flags will also output additional information.
Impact
======
The new feature allows the execution of tasks in a given order.
This can be used to debug side effects between tasks that are executed within the same scheduler run.
.. index:: CLI, ext:scheduler
@@ -0,0 +1,41 @@
.. include:: /Includes.rst.txt
.. _feature-88147:
==========================================================================
Feature: #88147 - Add possibility to configure the path to sitemap xslFile
==========================================================================
See :issue:`88147`
Description
===========
The xsl file to create a layout for a XML sitemap can now be configured on three levels:
1. for all sitemaps:
.. code-block:: typoscript
plugin.tx_seo.config.xslFile = EXT:myext/Resources/Public/CSS/mySite.xsl
2. for all sitemaps of a certain sitemapType:
.. code-block:: typoscript
plugin.tx_seo.config.<sitemapType>.sitemaps.xslFile = EXT:myext/Resources/Public/CSS/mySite.xsl
3. for a specific sitemap:
.. code-block:: typoscript
plugin.tx_seo.config.<sitemapType>.sitemaps.<sitemap>.config.xslFile = EXT:myext/Resources/Public/CSS/mySite.xsl
Impact
======
The value is inherited until it is overwritten.
If no value is specified at all, :file:`EXT:seo/Resources/Public/CSS/Sitemap.xsl` is used as default like before.
.. index:: Frontend, TypoScript, ext:seo
@@ -0,0 +1,76 @@
.. include:: /Includes.rst.txt
.. _feature-88818:
===================================================================
Feature: #88818 - Introduce events to modify CKEditor configuration
===================================================================
See :issue:`88818`
Description
===========
The following new PSR-14-based Events are introduced which allow
to modify CKEditor configuration.
- :php:`TYPO3\CMS\RteCKEditor\Form\Element\Event\AfterGetExternalPluginsEvent`
- :php:`TYPO3\CMS\RteCKEditor\Form\Element\Event\BeforeGetExternalPluginsEvent`
- :php:`TYPO3\CMS\RteCKEditor\Form\Element\Event\AfterPrepareConfigurationForEditorEvent`
- :php:`TYPO3\CMS\RteCKEditor\Form\Element\Event\BeforePrepareConfigurationForEditorEvent`
Example
=======
An example implementation how you could extend the existing
configuration to register a new plugin:
:file:`EXT:my_extension/Configuration/Services.yaml`
.. code-block:: yaml
services:
Vendor\MyExtension\EventListener\RteConfigEnhancer:
tags:
- name: event.listener
identifier: 'ext-myextension/rteConfigEnhancer'
method: 'beforeGetExternalPlugins'
event: TYPO3\CMS\RteCKEditor\Form\Element\Event\BeforeGetExternalPluginsEvent
- name: event.listener
identifier: 'ext-myextension/rteConfigEnhancer'
method: 'beforePrepareConfiguration'
event: TYPO3\CMS\RteCKEditor\Form\Element\Event\BeforePrepareConfigurationForEditorEvent
:file:`EXT:my_extension/Classes/EventListener/RteConfigEnhancer.php`
.. code-block:: php
namespace Vendor\MyExtension\EventListener;
use TYPO3\CMS\RteCKEditor\Form\Element\Event\BeforeGetExternalPluginsEvent;
use TYPO3\CMS\RteCKEditor\Form\Element\Event\BeforePrepareConfigurationForEditorEvent;
class RteConfigEnhancer
{
public function beforeGetExternalPlugins(BeforeGetExternalPluginsEvent $event): void
{
$data = $event->getData();
// @todo make useful decisions on fetched data
$configuration = $event->getConfiguration();
$configuration['example_plugin'] = [
'resource' => 'EXT:my_extension/Resources/Public/CKEditor/Plugins/ExamplePlugin/plugin.js'
];
$event->setConfiguration($configuration);
}
public function beforePrepareConfiguration(BeforePrepareConfigurationForEditorEvent $event): void
{
$data = $event->getData();
// @todo make useful decisions on fetched data
$configuration = $event->getConfiguration();
$configuration['extraPlugins'][] = 'example_plugin';
$event->setConfiguration($configuration);
}
}
.. index:: Backend, PHP-API, RTE, ext:rte_ckeditor
@@ -0,0 +1,27 @@
.. include:: /Includes.rst.txt
.. _feature-88901:
===================================================================
Feature: #88901 - Render all fields in ElementInformationController
===================================================================
See :issue:`88901`
Description
===========
The element information modal now shows all fields of the current record and
the selected type.
Impact
======
The TCA configuration :php:`showRecordFieldList` inside the section :php:`interface` is
not evaluated anymore and all occurrences have been removed.
A migration wizard is available that removes the option from your TCA and adds
a deprecation message to the deprecation log where code adaption has to take place.
.. index:: Backend
@@ -0,0 +1,85 @@
.. include:: /Includes.rst.txt
.. _feature-88921:
===============================================================
Feature: #88921 - New PSR-14 events in the PageLayoutView class
===============================================================
See :issue:`88921`
Description
===========
Two new PSR-14 events have been added to the :php:`PageLayoutView` class.
Those events can be used to add content into any column of a BackendLayout.
You can use this for example to show some content in a column without a ``colPos`` assigned.
The event :php:`BeforeSectionMarkupGeneratedEvent` can be used to add content above
the content elements of the column. The event :php:`AfterSectionMarkupGeneratedEvent`
can be used to add content below the content elements of the column.
You can use business logic to show content in specific columns.
E.g. for displaying content only in columns without any ``colPos``
in the BackendLayout configuration.
Example how to register the event listener in your own extension:
:file:`EXT:my_extension/Configuration/Services.yaml`
.. code-block:: yaml
services:
Vendor\MyExtension\Backend\View\PageLayoutViewDrawEmptyColposContent:
tags:
- name: event.listener
identifier: 'myColposListener'
before: 'backend-empty-colpos'
event: TYPO3\CMS\Backend\View\Event\AfterSectionMarkupGeneratedEvent
With :yaml:`before` and :yaml:`after`, you can make sure your own listener is
executed before or after the given identifiers.
:file:`EXT:my_extension/Classes/Backend/View/PageLayoutViewDrawEmptyColposContent.php`
.. code-block:: php
<?php
namespace Vendor\MyExtension\Backend\View;
class PageLayoutViewDrawEmptyColposContent
{
public function __invoke(AfterSectionMarkupGeneratedEvent $event): void
{
if (
!isset($event->getColumnConfig()['colPos'])
|| trim($event->getColumnConfig()['colPos']) === ''
) {
$content = $event->getContent();
$content .= <<<EOD
<div class="t3-page-ce-wrapper">
<div class="t3-page-ce">
<div class="t3-page-ce-header">Empty colpos</div>
<div class="t3-page-ce-body">
<div class="t3-page-ce-body-inner">
<div class="row">
<div class="col-xs-12">
This column has no "colPos". This is only for display Purposes.
</div>
</div>
</div>
</div>
</div>
</div>
EOD;
$event->setStopRendering(true);
$event->setContent($content);
}
}
}
With the :php:`$event->setStopRendering()` method,
you can make sure that no other listeners are triggered after the current listener.
.. index:: ext:backend, PHP-API
@@ -0,0 +1,43 @@
.. include:: /Includes.rst.txt
.. _feature-88962:
=======================================================================
Feature: #88962 - Re-implement old PIDupinRootline TypoScript condition
=======================================================================
See :issue:`88962`
Description
===========
The :typoscript:`PIDupinRootline` condition in TypoScript has been reimplemented within the Symfony
expression language.
A new property :typoscript:`tree.rootLineParentIds` has been added to the :typoscript:`tree` object which
is available in the Symfony expression language to provide checks for all parent
page IDs of the current rootline.
Impact
======
When using the classic :typoscript:`PIDupinRootline` condition, you can easily switch to the
condition with the new expression:
Old TypoScript condition syntax:
.. code-block:: typoscript
[PIDupinRootline = 30]
page.10.value = I'm on any subpage of page with uid=30.
[END]
New TypoScript condition syntax:
.. code-block:: typoscript
[30 in tree.rootLineParentIds]
page.10.value = I'm on any subpage of page with uid=30.
[end]
.. index:: Backend, Frontend, TypoScript
@@ -0,0 +1,32 @@
.. include:: /Includes.rst.txt
.. _feature-89032:
=============================================================
Feature: #89032 - Render fieldControl for SelectSingleElement
=============================================================
See :issue:`89032`
Description
===========
The missing rendering for the :html:`fieldControl` option for SelectSingleElements was added.
Impact
======
It is now possible to use the :html:`fieldControl` option for SelectSingleElements
to add nodes and wizards.
For example, add a link popup button to a select called "field_name" of the pages table:
.. code-block:: php
$GLOBALS['TCA']['pages']['columns']['field_name']['config']['fieldControl']['linkPopup'] = [
'renderType' => 'linkPopup',
];
.. index:: Backend, TCA, ext:backend
@@ -0,0 +1,77 @@
.. include:: /Includes.rst.txt
.. _feature-89139:
=======================================================================
Feature: #89139 - Add dependency injection support for console commands
=======================================================================
See :issue:`89139`
Description
===========
Support for dependency injection in console commands has been added.
Command dependencies can now be injected via constructor or other injection techniques.
Therefore, a new dependency injection tag :yaml:`console.command` has been added.
Commands tagged with :yaml:`console.command` are lazy loaded. That means they will only be
instantiated when they are actually executed, when the `help` subcommand is executed,
or when available schedulable commands are iterated.
The legacy command definition format :file:`Configuration/Commands.php` has been marked as deprecated.
Impact
======
It is recommended to configure dependency injection tags for all commands, as the legacy command
definition format :file:`Configuration/Commands.php` will be removed in TYPO3 v11.
Commands that have been configured via :yaml:`console.command` tag override legacy commands from
:file:`Configuration/Commands.php` without triggering a PHP :php:`E_USER_DEPRECATED` error for those commands.
Backwards compatibility with older TYPO3 version can be achieved by specifying both variants,
legacy configuration in :file:`Configuration/Commands.php` and new configuration via
:yaml:`console.command` tag.
Usage
=====
Add the :yaml:`console.command` tag to command classes.
Use the tag attribute :yaml:`command` to specify the command name.
The optional tag attribute :yaml:`schedulable` may be set to false
to exclude the command from the TYPO3 scheduler.
:file:`your_extension/Configuration/Services.yaml`
.. code-block:: yaml
services:
_defaults:
autowire: true
autoconfigure: true
public: false
MyVendor\MyExt\Command\FooCommand:
tags:
- name: 'console.command'
command: 'my:command'
schedulable: false
Command aliases are to be configured as separate tags.
The optional tag attribute :yaml:`alias` should be set to true for alias commands.
.. code-block:: yaml
MyVendor\MyExt\Command\BarCommand:
tags:
- name: 'console.command'
command: 'my:bar'
- name: 'console.command'
command: 'my:old-bar-command'
alias: true
schedulable: false
.. index:: CLI, PHP-API, ext:core
@@ -0,0 +1,36 @@
.. include:: /Includes.rst.txt
.. _feature-89551:
===================================================================
Feature: #89551 - Add fluidAdditionalAttributes to the form element
===================================================================
See :issue:`89551`
Description
===========
Allows to configure :yaml:`fluidAdditionalAttributes` within a form element:
.. code-block:: yaml
TYPO3:
CMS:
Form:
prototypes:
standard:
formElementsDefinition:
Form:
renderingOptions:
fluidAdditionalAttributes:
novalidate: 'novalidate'
Impact
======
For projects using their own Form template, the following attribute can be set on viewhelper :html:`formvh:form` as attribute:
:html:`additionalAttributes="{formvh:translateElementProperty(element: form, property: 'fluidAdditionalAttributes')}"`
.. index:: Fluid, ext:form
@@ -0,0 +1,50 @@
.. include:: /Includes.rst.txt
.. _feature-89644:
==========================================================================
Feature: #89644 - Add optional argument "fields" to editRecord ViewHelpers
==========================================================================
See :issue:`89644`
Description
===========
An optional argument "fields" is added to the :html:`uri.editRecord` and :html:`link.editRecord` ViewHelper.
This can contain the names of one or more database fields (comma separated).
If the argument "fields" is set, FormEngine creates a form to edit only these fields.
Impact
======
This ViewHelper passes the value given in the :html:`fields` argument to the backend route
`/record/edit` as :html:`columnsOnly` argument.
The functionality for :html:`columnsOnly` has always been there for the backend route
`/record/edit` even before this patch.
Example
=======
Create a link to edit the `tt_content.bodytext` field of record with uid 42:
.. code-block:: xml
<be:link.editRecord uid="42" table="tt_content" fields="bodytext" returnUrl="foo/bar">
Edit record
</be:link.editRecord>
Output:
.. code-block:: html
<a href="/typo3/index.php?route=/record/edit&edit[tt_content][42]=edit&returnUrl=foo/bar&columnsOnly=bodytext">
Edit record
</a>
.. index:: Fluid, ext:backend
@@ -0,0 +1,23 @@
.. include:: /Includes.rst.txt
.. _feature-89650:
=======================================================
Feature: #89650 - Allow line breaks in TCA descriptions
=======================================================
See :issue:`89650`
Description
===========
TCA description texts are passed through :php:`nl2br()` to allow line breaks which make longer description texts easier to read.
Impact
======
To make use of this feature simply format your description text with new lines. Those will be converted to :html:`<br>` tags when creating the output.
Installations that make use of TCA descriptions heavily might want to double check the formatting of those texts to avoid unwanted new lines.
.. index:: Backend, ext:backend
@@ -0,0 +1,219 @@
.. include:: /Includes.rst.txt
.. _feature-89738:
=======================================
Feature: #89738 - API for AJAX Requests
=======================================
See :issue:`89738`
Description
===========
Request
-------
In order to become independent of jQuery, a new API to perform AJAX requests has been introduced. This API implements
the `fetch API`_ available in all modern browsers.
To send a request, a new instance of `AjaxRequest` must be created which receives a single argument:
* :js:`url` (string) - The endpoint to send the request to
For compatibility reasons the :js:`Promise` prototype is extended to have basic support for jQuery's :js:`$.Deferred()`.
In all erroneous cases, the internal promise is rejected with an instance of `AjaxResponse` containing the original
`response object`_.
withQueryArguments()
~~~~~~~~~~~~~~~~~~~~
Clones the current request object and sets query arguments used for requests that get sent.
This method receives the following arguments:
* :js:`queryArguments` (string | array | object) - Optional: Query arguments to append to the url
The method returns a clone of the AjaxRequest instance.
get()
~~~~~
Sends a `GET` requests to the configured endpoint.
This method receives the following arguments:
* :js:`init` (object) - Optional: additional `request configuration`_ for the request object used by :js:`fetch()`
The method returns a promise resolved to an `AjaxResponse`.
Example:
.. code-block:: js
require(['TYPO3/CMS/Core/Ajax/AjaxRequest'], function (AjaxRequest) {
const request = new AjaxRequest('https://httpbin.org/json');
request.get().then(
async function (response) {
const data = await response.resolve();
console.log(data);
}, function (error) {
console.error('Request failed because of error: ' + error.status + ' ' + error.statusText);
}
);
});
post()
~~~~~~
Sends a `POST` requests to the configured endpoint. All responses are uncached by default.
This method receives the following arguments:
* :js:`data` (object) - Request body sent to the endpoint, get's converted to :js:`FormData`
* :js:`init` (object) - Optional: additional `request configuration`_ for the request object used by :js:`fetch()`
The method returns a promise resolved to an `AjaxResponse`.
Example:
.. code-block:: js
require(['TYPO3/CMS/Core/Ajax/AjaxRequest'], function (AjaxRequest) {
const body = {
foo: 'bar',
baz: 'quo'
};
const init = {
mode: 'cors'
};
const request = new AjaxRequest('https://example.com');
request.post(body, init).then(
async function (response) {
console.log('Data has been sent');
}, function (error) {
console.error('Request failed because of error: ' + error.status + ' ' + error.statusText);
}
);
});
put()
~~~~~
Sends a `PUT` requests to the configured endpoint. All responses are uncached by default.
This method receives the following arguments:
* :js:`data` (object) - Request body sent to the endpoint, get's converted to :js:`FormData`
* :js:`init` (object) - Optional: additional `request configuration`_ for the request object used by :js:`fetch()`
The method returns a promise resolved to an `AjaxResponse`.
Example:
.. code-block:: js
require(['TYPO3/CMS/Core/Ajax/AjaxRequest'], function (AjaxRequest) {
const fileField = document.querySelector('input[type="file"]');
const body = {
file: fileField.files[0],
username: 'Baz Bencer'
};
const request = new AjaxRequest('https://example.com');
request.put(body).then(null, function (error) {
console.error('Request failed because of error: ' + error.status + ' ' + error.statusText);
});
});
delete()
~~~~~~~~
Sends a `DELETE` requests to the configured endpoint. All responses are uncached by default.
This method receives the following arguments:
* :js:`data` (object) - Request body sent to the endpoint, get's converted to :js:`FormData`
* :js:`init` (object) - Optional: additional `request configuration`_ for the request object used by :js:`fetch()`
The method returns a promise resolved to an `AjaxResponse`.
Example:
.. code-block:: js
require(['TYPO3/CMS/Core/Ajax/AjaxRequest'], function (AjaxRequest) {
const request = new AjaxRequest('https://httpbin.org/delete');
request.delete().then(null, function (error) {
console.error('Request failed because of error: ' + error.status + ' ' + error.statusText);
}
);
});
abort()
~~~~~~~~~~
Aborts the request by using its instance of `AbortController`_.
Response
--------
Each response received is wrapped in an :js:`AjaxResponse` object. This object contains some methods to handle the response.
resolve()
~~~~~~~~~
Converts and returns the response body according to the **received** `Content-Type` header either into JSON or plaintext.
Example:
.. code-block:: js
require(['TYPO3/CMS/Core/Ajax/AjaxRequest'], function (AjaxRequest) {
new AjaxRequest('https://httpbin.org/json').get().then(
async function (response) {
// Response is automatically converted into a JSON object
const data = await response.resolve();
console.log(data);
}, function (error) {
console.error('Request failed because of error: ' + error.status + ' ' + error.statusText);
}
);
});
raw()
~~~~~
Returns the original response object, which is useful for e.g. add additional handling for specific headers in application
logic or to check the response status.
Example:
.. code-block:: js
require(['TYPO3/CMS/Core/Ajax/AjaxRequest'], function (AjaxRequest) {
new AjaxRequest('https://httpbin.org/status/200').get().then(
function (response) {
const raw = response.raw();
if (raw.headers.get('Content-Type') !== 'application/json') {
console.warn('We didn\'t receive JSON, check your request.');
}
}, function (error) {
console.error('Request failed because of error: ' + error.status + ' ' + error.statusText);
}
);
});
.. _`fetch API`: https://developer.mozilla.org/docs/Web/API/Fetch_API
.. _`request configuration`: https://developer.mozilla.org/en-US/docs/Web/API/Request#Properties
.. _`response object`: https://developer.mozilla.org/en-US/docs/Web/API/Response
.. _`AbortController`: https://developer.mozilla.org/en-US/docs/Web/API/AbortController
.. index:: JavaScript, ext:core
@@ -0,0 +1,47 @@
.. include:: /Includes.rst.txt
.. _feature-89870:
===============================================================
Feature: #89870 - New PSR-14 Events for Extbase-related signals
===============================================================
See :issue:`89870`
Description
===========
The following new PSR-14-based Events are introduced which allow
to modify various concerns in the MVC and persistence stacks of Extbase internals.
- :php:`TYPO3\CMS\Extbase\Event\Mvc\AfterRequestDispatchedEvent`
- :php:`TYPO3\CMS\Extbase\Event\Mvc\BeforeActionCallEvent`
- :php:`TYPO3\CMS\Extbase\Event\Persistence\AfterObjectThawedEvent`
- :php:`TYPO3\CMS\Extbase\Event\Persistence\ModifyQueryBeforeFetchingObjectDataEvent`
- :php:`TYPO3\CMS\Extbase\Event\Persistence\ModifyResultAfterFetchingObjectDataEvent`
- :php:`TYPO3\CMS\Extbase\Event\Persistence\EntityAddedToPersistenceEvent`
- :php:`TYPO3\CMS\Extbase\Event\Persistence\EntityFinalizedAfterPersistenceEvent`
- :php:`TYPO3\CMS\Extbase\Event\Persistence\EntityUpdatedInPersistenceEvent`
- :php:`TYPO3\CMS\Extbase\Event\Persistence\EntityRemovedFromPersistenceEvent`
- :php:`TYPO3\CMS\Extbase\Event\Persistence\EntityPersistedEvent`
Impact
======
Existing signals are replaced and should not be used anymore, as PSR-14 event classes exactly specify what can be modified or listened to.
The following signals should not be used anymore then:
- :php:`TYPO3\CMS\Extbase\Mvc\Dispatcher::afterRequestDispatch`
- :php:`TYPO3\CMS\Extbase\Mvc\Controller\ActionController::beforeCallActionMethod`
- :php:`TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::afterMappingSingleRow`
- :php:`TYPO3\CMS\Extbase\Persistence\Generic\Backend::beforeGettingObjectData`
- :php:`TYPO3\CMS\Extbase\Persistence\Generic\Backend::afterGettingObjectData`
- :php:`TYPO3\CMS\Extbase\Persistence\Generic\Backend::afterInsertObject`
- :php:`TYPO3\CMS\Extbase\Persistence\Generic\Backend::endInsertObject`
- :php:`TYPO3\CMS\Extbase\Persistence\Generic\Backend::afterUpdateObject`
- :php:`TYPO3\CMS\Extbase\Persistence\Generic\Backend::afterPersistObject`
- :php:`TYPO3\CMS\Extbase\Persistence\Generic\Backend::afterRemoveObject`
.. index:: PHP-API, ext:extbase
@@ -0,0 +1,29 @@
.. include:: /Includes.rst.txt
.. _feature-89894:
===============================================================================
Feature: #89894 - Separate system extensions from 3rd-party extensions visually
===============================================================================
See :issue:`89894`
Description
===========
The Extension Manager in TYPO3 allows backend users to list, activate, deactivate, configure
and possibly add/remove extensions from the system. When using the Extension Manager,
backend users work with either core extensions (system extensions) or 3rd-party extensions,
depending on their task.
The extension list shown in the Extension Manager can now be filtered by certain extension types (system and 3rd-party extensions).
Impact
======
A limited list of extensions, either system or 3rd-party extensions, makes it easier for backend users
to find the extension they intend to work with and/or to get a quick overview which extensions are
currently installed (e.g. 3rd-party extensions). This improves the usability of the backend for integrators/administrators.
.. index:: Backend, ext:extensionmanager
@@ -0,0 +1,23 @@
.. include:: /Includes.rst.txt
.. _feature-89929:
===============================
Feature: #89929 - Galician flag
===============================
See :issue:`89929`
Description
===========
When adding a new language to a site or the system (`sys_language`) the Galician flag (ISO-639-1 Code "gl") is now available for selection.
Impact
======
A previous error, where the flag for Greenlandic was available (ISO Code "kl") under the "GL" shortcut, was resolved with this feature,
as both flags now represent the proper ISO code.
.. index:: Backend, ext:core
@@ -0,0 +1,32 @@
.. include:: /Includes.rst.txt
.. _feature-89978:
=================================================================================
Feature: #89978 - Introduce Status Report for insecure exception handler settings
=================================================================================
See :issue:`89978`
Description
===========
When using a debug exception handler in production (either by configuring it explicitly
or by using the wrong application context) stack traces may disclose information.
To avoid such setups a new status report has been introduced that warns administrators if a debug exception handler is configured.
Impact
======
To mitigate the information disclosure, a new status report has
been introduced:
- if display errors is set to 1 (-> uses DebugExceptionHandler setting)
and context is Production, an Error is displayed
- if display errors is set to 1 (-> uses DebugExceptionHandler setting)
and context is Development, a Warning is displayed
- if the production exception handler setting is configured to use the
DebugExceptionHandler, an Error is displayed
.. index:: Backend, LocalConfiguration, ext:reports
@@ -0,0 +1,48 @@
.. include:: /Includes.rst.txt
.. _feature-90026:
=====================================================================
Feature: #90026 - Expose internal typoLinkParts in TypolinkViewHelper
=====================================================================
See :issue:`90026`
Description
===========
Parameters being generated internally by TypoLink using
:html:`<f:link.typolink parts-as="typoLinkParts">` view helper are exposed as
variable and can be used in Fluid templates.
View helper attribute :html:`parts-as` (default :html:`typoLinkParts`) allows to define the
variable name to be used containing the following internal parts:
* url
* target
* class
* title
* additionalParams
Details for these internal parts are documented for :typoscript:`typolink.parameter`
in `TypoScript reference`_
.. _TypoScript reference: https://docs.typo3.org/m/typo3/reference-typoscript/main/en-us/Functions/Typolink.html?highlight=typolink#parameter
Impact
======
Multiple instructions for attribute :html:`parameter` (e.g. persisted to entity
record) can be used individually.
.. code-block:: html
<f:link.typolink parameter="123 _top news title" parts-as="parts">
{parts.url}
{parts.target}
{parts.class}
{parts.title}
{parts.additionalParams}
</f:link.typolink>
.. index:: Fluid, Frontend, ext:fluid
@@ -0,0 +1,43 @@
.. include:: /Includes.rst.txt
.. _feature-90042:
=========================================================
Feature: #90042 - Customize special page icons by doktype
=========================================================
See :issue:`90042`
Description
===========
The page icon in the pagetree can now be fully customized for own doktypes.
Before this it was possible to provide one icon. This icon however was not used when the page was in one of the following states:
* Page is hidden in navigation
* Page is site-root
* Page contains content from another page
* Page contains content from another page AND is hidden in navigation
Provide custom icons in TCA like so:
:file:`EXT:my_extension/Configuration/TCA/Overrides/pages.php`
.. code-block:: php
'ctrl' => [
'typeicon_classes' => [
'123' => "your-icon",
'123-contentFromPid' => "your-icon-contentFromPid",
'123-root' => "your-icon-root",
'123-hideinmenu' => "your-icon-hideinmenu",
],
]
Icons you don't provide will automatically fall back to the variant for regular page doktypes.
.. note::
Make sure to add the additional icons using the IconRegistry!
.. index:: TCA, ext:core
@@ -0,0 +1,20 @@
.. include:: /Includes.rst.txt
.. _feature-90052:
===========================================================================
Feature: #90052 - Form YAML configuration available in configuration module
===========================================================================
See :issue:`90052`
Description
===========
If the Form system extension is installed, a new entry
``Form: YAML Configuration`` is available in the menu of the
``SYSTEM > Configuration`` module of the lowlevel system extension.
When selected, the parsed YAML configuration of the form setup is displayed.
.. index:: Backend, ext:lowlevel, ext:form
@@ -0,0 +1,83 @@
.. include:: /Includes.rst.txt
.. _feature-90068:
=====================================================================
Feature: #90068 - Implement better FileDumpController
=====================================================================
See :issue:`90068`
Description
===========
FileDumpController can now process UIDs of sys_file_reference records and
can adopt image sizes to records of sys_file.
Following URI-Parameters are now possible:
+ :php:`t` (*Type*): Can be one of :php:`f` (`sys_file`), :php:`r` (`sys_file_reference`) or :php:`p` (`sys_file_processedfile`)
+ :php:`f` (*File*): Use it for a UID of table :sql:`sys_file`
+ :php:`r` (*Reference*): Use it for a UID of table :sql:`sys_file_reference`
+ :php:`p` (*Processed*): Use it for a UID of table :sql:`sys_file_processedfile`
+ :php:`s` (*Size*): Use it for a UID of table :sql:`sys_file_processedfile`
+ :php:`cv` (*CropVariant*): In case of `sys_file_reference`, you can assign it a cropping variant
You have to choose one of these parameters: :php:`f`, :php:`r` or :php:`p`. It is not possible
to use them multiple times in one request.
The Parameter :php:`s` has following syntax: width:height:minW:minH:maxW:maxH. You
can leave this Parameter empty to load the file in original size. Parameter :php:`width`
and :php:`height` can feature the trailing :typoscript:`c` or :typoscript:`m` indicator like known from TS.
See the following example on how to create a URI using the :php:`FileDumpController` for
a sys_file record with a fixed image size:
.. code-block:: php
$queryParameterArray = ['eID' => 'dumpFile', 't' => 'f'];
$queryParameterArray['f'] = $resourceObject->getUid();
$queryParameterArray['s'] = '320c:280c';
$queryParameterArray['token'] = GeneralUtility::hmac(implode('|', $queryParameterArray), 'resourceStorageDumpFile');
$publicUrl = GeneralUtility::locationHeaderUrl(PathUtility::getAbsoluteWebPath(Environment::getPublicPath() . '/index.php'));
$publicUrl .= '?' . http_build_query($queryParameterArray, '', '&', PHP_QUERY_RFC3986);
In this example crop variant :php:`default` and an image size of 320:280 will be
applied to a sys_file_reference record:
.. code-block:: php
$queryParameterArray = ['eID' => 'dumpFile', 't' => 'r'];
$queryParameterArray['f'] = $resourceObject->getUid();
$queryParameterArray['s'] = '320c:280c:320:280:320:280';
$queryParameterArray['cv'] = 'default';
$queryParameterArray['token'] = GeneralUtility::hmac(implode('|', $queryParameterArray), 'resourceStorageDumpFile');
$publicUrl = GeneralUtility::locationHeaderUrl(PathUtility::getAbsoluteWebPath(Environment::getPublicPath() . '/index.php'));
$publicUrl .= '?' . http_build_query($queryParameterArray, '', '&', PHP_QUERY_RFC3986);
This example shows the usage how to create a URI to load an image of
sys_file_processedfile:
.. code-block:: php
$queryParameterArray = ['eID' => 'dumpFile', 't' => 'p'];
$queryParameterArray['p'] = $resourceObject->getUid();
$queryParameterArray['token'] = GeneralUtility::hmac(implode('|', $queryParameterArray), 'resourceStorageDumpFile');
$publicUrl = GeneralUtility::locationHeaderUrl(PathUtility::getAbsoluteWebPath(Environment::getPublicPath() . '/index.php'));
$publicUrl .= '?' . http_build_query($queryParameterArray, '', '&', PHP_QUERY_RFC3986);
There are some restriction while using the new URI-Parameters:
+ You can't assign any size parameter to processed files, as they are already resized.
+ You can't apply CropVariants to `sys_file` and `sys_file_processedfile` records.
Impact
======
No impact, as this class was extended only. It's fully backwards compatible.
.. index:: FAL, ext:core
@@ -0,0 +1,24 @@
.. include:: /Includes.rst.txt
.. _feature-90114:
=======================================================
Feature: #90114 - Make translation of filelist optional
=======================================================
See :issue:`90114`
Description
===========
The filelist module now takes :php:`$GLOBALS['TCA']['sys_file_metadata']['ctrl']['languageField']`
into account. By unsetting the field, translations in the filelist module are no longer possible.
Impact
======
If :php:`$GLOBALS['TCA']['sys_file_metadata']['ctrl']['languageField']` is set to an empty value,
translations are disabled for the filelist module.
.. index:: Backend, FAL, TCA, ext:filelist
@@ -0,0 +1,24 @@
.. include:: /Includes.rst.txt
.. _feature-90136:
====================================================================
Feature: #90136 - Show application context in the Environment module
====================================================================
See :issue:`90136`
Description
===========
The "Environment Overview" card in the admin tool will now show the
application context the TYPO3 instance is running with.
Impact
======
Administrators can now look up the application context from inside the admin tool without
having to log into the TYPO3 backend.
.. index:: ext:install
@@ -0,0 +1,50 @@
.. include:: /Includes.rst.txt
.. _feature-90168:
=========================================
Feature: #90168 - Introduce Modal Actions
=========================================
See :issue:`90168`
Description
===========
Action buttons in modals created by the :js:`TYPO3/CMS/Backend/Modal` module may
now make use of :js:`TYPO3/CMS/Backend/ActionButton/ImmediateAction` and
:js:`TYPO3/CMS/Backend/ActionButton/DeferredAction`.
As an alternative to the existing :js:`trigger` option, the new option
:js:`action` may be used with an instance of the previously mentioned modules.
Example:
.. code-block:: js
Modal.confirm('Header', 'Some content', Severity.error, [
{
text: 'Based on trigger()',
trigger: function () {
console.log('Vintage!');
}
},
{
text: 'Based on action',
action: new DeferredAction(() => {
return new AjaxRequest('/any/endpoint').post({});
})
}
]);
Impact
======
Activating any action disables all buttons in the modal. Once the action is
done, the modal disappears automatically.
Buttons of the type :js:`DeferredAction` render a spinner on activation into the
button.
.. index:: Backend, JavaScript, ext:backend
@@ -0,0 +1,48 @@
.. include:: /Includes.rst.txt
.. _feature-90203:
===================================================================
Feature: #90203 - Make workspace available in TypoScript conditions
===================================================================
See :issue:`90203`
Description
===========
A new TypoScript expression language variable :typoscript:`workspace` has been added.
It can be used to match a given expression against common workspace parameters.
Currently, the parameters :typoscript:`workspaceId`, :typoscript:`isLive` and :typoscript:`isOffline` are supported.
Examples
--------
Match the current workspace id:
.. code-block:: typoscript
[workspace.workspaceId === 3]
# Current workspace id equals: 3
[end]
Match against current workspace state:
.. code-block:: typoscript
[workspace.isLive]
# Current workspace is live
[end]
[workspace.isOffline]
# Current workspace is offline
[end]
Impact
======
The new feature allows matching against several workspace parameters within TypoScript.
.. index:: TypoScript
@@ -0,0 +1,40 @@
.. include:: /Includes.rst.txt
.. _feature-90213:
============================================================
Feature: #90213 - Support 'bit and' in TypoScript stdWrap_if
============================================================
See :issue:`90213`
Description
===========
It is now possible to use :typoscript:`bitAnd` within TypoScript :typoscript:`if`.
TYPO3 uses bits to store radio and checkboxes via TCA.
Without this feature one would need to check whether any possible bit value is in a
list. With this feature a simple comparison whether the expected value is part of the
bit set is possible.
Example
=======
An example usage could look like this:
.. code-block:: typoscript
hideDefaultLanguageOfPage = TEXT
hideDefaultLanguageOfPage {
value = 0
value {
override = 1
override.if {
bitAnd.field = l18n_cfg
value = 1
}
}
}
.. index:: ext:frontend, TypoScript
@@ -0,0 +1,82 @@
.. include:: /Includes.rst.txt
.. _feature-90234:
==========================================================================
Feature: #90234 - Introduce CacheHashConfiguration and matching indicators
==========================================================================
See :issue:`90234`
Description
===========
Settings for :php:`$GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']` are modelled
in class :php:`CacheHashConfiguration` which takes care of validating configuration.
It also determines whether corresponding aspects apply to a given URL
parameter.
Besides exact matches (*equals*) it is possible to apply partial matches at
the beginning of a parameter (*startsWith*) or inline occurrences (*contains*).
URL parameter names are prefixed with the following indicators:
* :php:`=` (*equals*): exact match, default behavior if not given
* :php:`^` (*startsWith*): matching the beginning of a parameter name
* :php:`~` (*contains*): matching any inline occurrence in a parameter name
These indicators can be used for all previously existing sub-properties
:php:`cachedParametersWhiteList`, :php:`excludedParameters`, :php:`excludedParametersIfEmpty`
and :php:`requireCacheHashPresenceParameters`.
Example (excerpt of `LocalConfiguration.php`)
---------------------------------------------
.. code-block:: php
$GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash'] = [
'excludedParameters' => [
'utm_source',
'utm_medium',
'^utm_', // making previous two obsolete
],
'excludedParametersIfEmpty' => [
'^tx_my_plugin[aspects]',
'tx_my_plugin[filter]',
],
];
Impact
======
Configuration related to *cHash* URL parameter supports partial matches which
overcomes the previous necessity to explicitly state all parameter names to be
excluded.
For instance instead of having exclude items like
.. code-block:: php
'excludedParameters' => [
'tx_my[data][uid]',
'tx_my[data][category]',
'tx_my[data][order]',
'tx_my[data][origin]',
...
],
partial matches allow to simplify the configuration and consider all items having
:php:`tx_my[data]` (or :php:`tx_my[data][` to be more specific) as prefix like
.. code-block:: php
'excludedParameters' => [
'^tx_my[data][',
...
],
The present configuration for the :php:`cHash` section is still supported - there is
no syntactical requirement to adjust those changes.
.. index:: Frontend, LocalConfiguration, ext:frontend
@@ -0,0 +1,48 @@
.. include:: /Includes.rst.txt
.. _feature-90249:
=============================================================================
Feature: #90249 - New PSR-14 events for existing package-related Signal Slots
=============================================================================
See :issue:`90249`
Description
===========
PSR-14-based event dispatching allows for TYPO3 extensions or PHP packages to
extend TYPO3 Core functionality in an exchangeable way.
The following new PSR-14 events have been introduced:
- :php:`TYPO3\CMS\Core\Package\Event\PackagesMayHaveChangedEvent`
- :php:`TYPO3\CMS\Core\Package\Event\AfterPackageActivationEvent`
- :php:`TYPO3\CMS\Core\Package\Event\AfterPackageDeactivationEvent`
- :php:`TYPO3\CMS\Core\Package\Event\BeforePackageActivationEvent`
- :php:`TYPO3\CMS\Extensionmanager\Event\AfterExtensionDatabaseContentHasBeenImportedEvent`
- :php:`TYPO3\CMS\Extensionmanager\Event\AfterExtensionStaticDatabaseContentHasBeenImportedEvent`
- :php:`TYPO3\CMS\Extensionmanager\Event\AfterExtensionFilesHaveBeenImportedEvent`
- :php:`TYPO3\CMS\Extensionmanager\Event\AvailableActionsForExtensionEvent`
They replace the existing Extbase-based Signal Slots:
- :php:`PackageManagement::packagesMayHaveChanged`
- :php:`TYPO3\CMS\Extensionmanager\Utility\InstallUtility::afterExtensionInstall`
- :php:`TYPO3\CMS\Extensionmanager\Utility\InstallUtility::afterExtensionUninstall`
- :php:`TYPO3\CMS\Extensionmanager\Utility\InstallUtility::afterExtensionT3DImport`
- :php:`TYPO3\CMS\Extensionmanager\Utility\InstallUtility::afterExtensionStaticSqlImport`
- :php:`TYPO3\CMS\Extensionmanager\Utility\InstallUtility::afterExtensionFileImport`
- :php:`TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService::willInstallExtensions`
- :php:`TYPO3\CMS\Extensionmanager\ViewHelper\ProcessAvailableActionsViewHelper::processActions`
Impact
======
It is now possible to add listeners to the new PSR-14 Events which
define a clear API what can be read or modified.
The listeners can be added to the :file:`Configuration/Services.yaml` as
it is done in TYPO3's shipped extensions as well.
.. index:: PHP-API, ext:core
@@ -0,0 +1,20 @@
.. include:: /Includes.rst.txt
.. _feature-90262:
===========================================================
Feature: #90262 - Add Argon2id to password hash algorithms
===========================================================
See :issue:`90262`
Description
===========
The hash algorithm `argon2id` is now available and can be selected in the
section `Configuration Presets` of the admin tools > settings module if
the PHP instance supports it.
Argon2id is usually available on systems with PHP version 7.3 or higher.
.. index:: Backend, Frontend, PHP-API, ext:install
@@ -0,0 +1,27 @@
.. include:: /Includes.rst.txt
.. _feature-90265:
=======================================================
Feature: #90265 - Show dispatched Events in Admin Panel
=======================================================
See :issue:`90265`
Description
===========
To promote the new PSR-14 Events and to make it easier for people to see which
kinds of events may be used, the admin panel displays all events that are
dispatched in the current request with their parameters.
Impact
======
The Admin Panel has a new section called "Events" (in "Debug") which shows all
events with their respective values that have been dispatched during the current
request. To allow smooth navigating of these objects, the symfony var-dumper
component is used.
.. index:: PHP-API, ext:adminpanel
@@ -0,0 +1,81 @@
.. include:: /Includes.rst.txt
.. _feature-90266:
==============================================
Feature: #90266 - Fluid-based email templating
==============================================
See :issue:`90266`
Description
===========
TYPO3 now supports sending template-based emails for multi-part and HTML-based
emails out-of-the-box. The email contents are built with Fluid Templating Engine.
TYPO3's backend functionality already ships with a default layout
for templated emails, which can be tested out in TYPO3's install tool test email functionality.
It is also possible to set a default mode for sending out emails via :php:`$GLOBALS['TYPO3_CONF_VARS']['MAIL']['format']`
which can be :php:`both`, :php:`plain` or :php:`html`.
This option can however overridden by Extension authors in their use cases.
All Fluid-based template paths can be configured via
:file:`LocalConfiguration.php`:
* :php:`$GLOBALS['TYPO3_CONF_VARS']['MAIL']['layoutRootPaths']`
* :php:`$GLOBALS['TYPO3_CONF_VARS']['MAIL']['partialRootPaths']`
* :php:`$GLOBALS['TYPO3_CONF_VARS']['MAIL']['templateRootPaths']`
where TYPO3 reserves all array keys below :php:`100` for internal purposes. If you want to provide custom templates or layouts,
set this in your :file:`LocalConfiguration.php` / :file:`AdditionalConfiguration.php` file:
* :php:`$GLOBALS['TYPO3_CONF_VARS']['MAIL']['templateRootPaths'][700] = 'EXT:my_site_extension/Resources/Private/Templates/Email';`
* :php:`$GLOBALS['TYPO3_CONF_VARS']['MAIL']['layoutRootPaths'][700] = 'EXT:my_site_extension/Resources/Private/Layouts';`
In addition, it is possible to define a section within the Fluid template,
which - if set - takes precedence over the :php:`subject()` method.
Impact
======
TYPO3 now sends out templated messages for system emails in both plaintext and HTML format.
It is possible to use the same API in your custom extension like this:
.. code-block:: php
$email = GeneralUtility::makeInstance(FluidEmail::class);
$email
->to('contact@acme.com')
->from(new Address('jeremy@acme.com', 'Jeremy'))
->subject('TYPO3 loves you - here is why')
->format('html') // only HTML mail
->setTemplate('TipsAndTricks')
->assign('mySecretIngredient', 'Tomato and TypoScript');
GeneralUtility::makeInstance(Mailer::class)->send($email);
Defining a custom email subject in a custom template:
.. code-block:: html
<f:section name="Subject">New Login at "{typo3.sitename}"</f:section>
Building templated emails with Fluid also allows to define the language key,
and use this within the Fluid template:
.. code-block:: php
$email = GeneralUtility::makeInstance(FluidEmail::class);
$email
->to('contact@acme.com')
->assign('language', 'de');
.. code-block:: html
<f:translate languageKey="{language}" id="LLL:my_ext/Resources/Private/Language/emails.xml:subject" />
.. index:: Fluid, ext:core
@@ -0,0 +1,81 @@
.. include:: /Includes.rst.txt
.. _feature-90267:
==============================================================
Feature: #90267 - Custom placeholder processing in site config
==============================================================
See :issue:`90267`
Description
===========
The Yaml import for site configuration was changed to allow custom placeholder processors.
Impact
======
It is now possible to register a new placeholder processor:
:file:`LocalConfiguration.php`:
.. code-block:: php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['yamlLoader']['placeholderProcessors'][\Vendor\MyExtension\PlaceholderProcessor\CustomPlaceholderProcessor::class] = [];
There are some options available to sort or disable placeholder processors if necessary.
.. code-block:: php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['yamlLoader']['placeholderProcessors'][\Vendor\MyExtension\PlaceholderProcessor\CustomPlaceholderProcessor::class] = [
'before' => [
\TYPO3\CMS\Core\Configuration\Processor\Placeholder\ValueFromReferenceArrayProcessor::class
],
'after' => [
\TYPO3\CMS\Core\Configuration\Processor\Placeholder\EnvVariableProcessor::class
],
'disabled' => false
];
New placeholder processors must implement the :php:`\TYPO3\CMS\Core\Configuration\Processor\Placeholder\PlaceholderProcessorInterface`
Placeholders look mostly like functions.
So an implementation may look like the following:
.. code-block:: php
class ExamplePlaceholderProcessor implements PlaceholderProcessorInterface
{
public function canProcess(string $placeholder, array $referenceArray): bool
{
return strpos($placeholder, '%example(') !== false;
}
public function process(string $value, array $referenceArray)
{
// do some processing
$result = $this->getValue($value);
// Throw this exception if the placeholder can't be substituted
if (!$envVar) {
throw new \UnexpectedValueException('Value not found', 1581596096);
}
return $result;
}
}
This may be used like the following in the site configuration:
.. code-block:: yaml
someVariable: '%example(somevalue)%'
anotherVariable: 'inline::%example(anotherValue)%::placeholder'
If a new processor returns a string or number, it may also be used inline as above.
If it returns an array, it cannot be used inline since the whole content will be replaced with the new value.
.. index:: Backend, PHP-API, ext:core
@@ -0,0 +1,30 @@
.. include:: /Includes.rst.txt
.. _feature-90298:
=====================================================
Feature: #90298 - Improve user info in BE User module
=====================================================
See :issue:`90298`
Description
===========
The *Backend users* module has been improved by showing more details of TYPO3
Administrators and Editors:
- All assigned groups, including subgroups, are now evaluated
- All data which can be set in the backend user or an assigned group are now shown including allowed page types
- Read & write access to tables
- A new "detail view" for a TYPO3 Backend user has been added
Impact
======
Comparing users is more powerful now. It is now easier for TYPO3 Administrators
to check backend user permissions without the need to switch to the actual user
and test the behaviour.
.. index:: Backend, ext:beuser
@@ -0,0 +1,187 @@
.. include:: /Includes.rst.txt
.. _feature-90333:
===========================
Feature: #90333 - Dashboard
===========================
See :issue:`90333`
Description
===========
A dashboard is introduced into TYPO3 to show relevant information to
the current logged in user.
Every user with access to this backend module can now have one or more personal
dashboards. Each dashboard can contain several widgets. Which widgets and in which
order the widgets are shown is up to the users themselves.
As an integrator, you have the possibility to create dashboard templates. You can
mark the template as a default template so it will be created by default for every
new user.
As a developer, you can create your own widgets. Just use one of the available
abstracts, which will be extended in the future, and extend it with your own
information.
You can find the new dashboard in the toolbar in the top of your window.
Available widgets
^^^^^^^^^^^^^^^^^
The following widgets are shipped by core extensions now:
* TYPO3 news: A widget showing the latest 5 news items from typo3.org (EXT:dashboard)
* TYPO3 security advisories: A widget showing the latest 5 security advisories from typo3.org (EXT:dashboard)
* TYPO3: This widget will show you some background information about TYPO3 and shows the current version of TYPO3 installed (EXT:dashboard)
* Getting started with TYPO3: This widget will provide a link to the Getting Started Tutorial (EXT:dashboard)
* TypoScript Template Reference: This widget will provide a link to the TypoScript Template Reference (EXT:dashboard)
* TSconfig Reference: This widget will provide a link to the TSconfig Reference (EXT:dashboard)
* Number of errors in system log: Shows the number of errors in the sys_log grouped by day for the last month (EXT:dashboard)
* Type of backend users: A widget to show the different types of backend users (EXT:dashboard)
* Failed Logins: This widget will show you the number of failed logins during the last 24 hours (EXT:dashboard)
Creating your own widget
^^^^^^^^^^^^^^^^^^^^^^^^
Besides the widgets shipped with TYPO3 core, you can also write your own widget. To
do so, you can extend one of the WidgetAbstracts available in EXT:dashboard.
* :php:`AbstractWidget`: a basic abstract that can be used as the start of simple widgets
* :php:`AbstractRssWidget`: with this abstract it is easy to create a widget showing a RSS feed
* :php:`AbstractListWidget`: this abstract will give you an easy start to show a list of items
* :php:`AbstractCtaButtonWidget`: when you want to show a Call-To-Action button, this is the right abstract
* :php:`AbstractChartWidget`: the base of all chart widgets
* :php:`AbstractBarChartWidget`: when you want to show a widget with a bar-chart you can extend this class
* :php:`AbstractDoughnutChartWidget`: this abstract gives you the possibility to create a doughnut-chart widget
* :php:`AbstractNumberWithIconWidget`: this abstract will give you the possibility to show a title, number and an icon
By extending one of those abstracts, and providing it with the needed data, you are able to
have a new widget quite fast. The only thing that is left is to register the widget.
Tag your widget in :file:`EXT:your_extension/Configuration/Services.yaml`:
.. code-block:: yaml
# Variant 1, widget identifier as attribute
Vendor\Extension\Widgets\MyFirstWidget:
arguments: ['widget-identifier-1']
tags:
- name: dashboard.widget
identifier: widget-identifier-1
widgetGroups: 'general'
# Variant 2, custom service name, allows multiple widget identifiers
# to share the same class
widget.identifier:
class: Vendor\Extension\Widgets\MySecondWidget
arguments: ['widget-identifier-1']
tags:
- name: dashboard.widget
# If omitted, the identifier would be the service name, thus 'widget.identifier'
identifier: widget-identifier-2
widgetGroups: 'general, typo3'
Every widget needs a unique identifier, the implementing class and at least one
associated widget group. Multiple widget groups are separated by comma.
Configuring Widget Groups
^^^^^^^^^^^^^^^^^^^^^^^^^
Every widget is attached to one or more widget groups. Those groups are shown in the
modal when adding a new widget to your dashboard. In this way you can group the available
widgets to get a clear overview for your users. By default the following widget groups are
available:
* `widgetGroup-general`: Widgets with a more generic purpose
* `widgetGroup-systemInfo`: Widgets which provide system related information
* `widgetGroup-typo3`: Widgets with information regarding the TYPO3 product or community
* `widgetGroup-documentation`: Widgets with links to TYPO3 documentation
You can also configure your own widget groups. To do so, you create a file :file:`EXT:your_extension/Configuration/Backend/DashboardWidgetGroups.php`.
In that file you specify the information of the groups.
.. code-block:: php
return [
'widgetGroup-myOwnGroup' => [
'title' => 'LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:widget_group.myOwnGroup',
],
];
First you have the identifier as the key. This identifier is used to map widgets to this
group. You only have one property and that is the title. You can add a simple text, or a
translation string like in the example above.
Defining Dashboard Presets
^^^^^^^^^^^^^^^^^^^^^^^^^^
You have the possibility to create dashboard presets. Those
presets are used when a user is creating a new dashboard. He can choose one of the available presets.
In a preset you can define which widgets and in which order those widgets will be added to the dashboard when created.
So for example, if you want to give editors the possibility to add a dashboard with several
SEO related widgets, you can create a dashboard preset and add all the useful widgets on that.
When a user creates a dashboard based on that preset, all those widgets will be initially added to
that dashboard.
To define those dashboard presets, you can create a file :file:`EXT:your_extension/Configuration/Backend/DashboardPresets.php`.
In that file you specify the information of the presets.
.. code-block:: php
return [
'dashboardPreset-myOwnPreset' => [
'title' => 'LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:dashboard.myOwnPreset',
'description' => 'LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:dashboard.myOwnPreset.description',
'iconIdentifier' => 'content-dashboard',
'defaultWidgets' => ['widget-identifier-1', 'widget-identifier-2'],
'showInWizard' => true
],
];
You start again with the dashboard preset identifier which should be unique. Every preset needs a title, description, iconIdentifier, some widgets and a flag if the
preset should be shown in the wizard to create a new dashboard. This last setting is to make it possible to not show it as a preset, but it can be used to
create this dashboard preset by default for new users.
Automatically create a dashboard for new users
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you have a new user in your backend, you might want to kickstart that user and provide a
basic dashboard. You can do this by defining which dashboard presets should be created by default
when a user gets created or when a user deletes all his dashboards.
You can define which dashboards will be created automatically by using the following TSconfig setting:
.. code-block:: typoscript
options.dashboard.dashboardPresetsForNewUsers = default, dashboardPreset-myOwnPreset
You can add the identifiers of multiple presets in a comma separated list.
Permissions
^^^^^^^^^^^
As widgets might contain sensitive information, it is also possible to define the permissions
of the widgets on a group base. In the backend group settings you have the possibility to allow
specific widgets. Only those widgets will be available for users in that group. Admin users
have access to all widgets by default.
Impact
======
This is a new backend module and will not replace any old features. If the dashboard
extension is installed, it will be the default startup page in TYPO3 Backend.
.. index:: Backend, ext:dashboard
@@ -0,0 +1,94 @@
.. include:: /Includes.rst.txt
.. _feature-90348:
============================================================
Feature: #90348 - Fluid-based replacement for PageLayoutView
============================================================
See :issue:`90348`
Description
===========
A completely rewritten replacement for PageLayoutView has been added. This replacement allows third parties
to override and extend any part of the "page" module's output by overriding Fluid templates.
Although it is visually identical to the old :php:`PageLayoutView`'s output, the new alternative has a number of benefits:
* The grid defined in a BackendLayout is now represented as objects which are assigned to Fluid templates and can be iterated over
to render rows, columns and records.
* Custom BackendLayout implementations can now manipulate every part of the configuration that determines
how the page module is rendered - or completely replace the logic that draws the "columns" and "languages" views of the page BE module.
* Custom BackendLayout implementations can also provide custom classes for LanguageColumn, Grid, GridRow, GridColumn and GridColumnItem instances
that are assigned to and used by Fluid templates to render the page layout.
* Headers, footers and previews for content types can be created in Fluid in a way that groups
each of these component templates by the content type (CType) value of content records.
* Any part of the page layout can now be rendered elsewhere by creating instances of any of the "grid" objects and assigning them to Fluid templates.
* The "grid" structure of BackendLayouts can be manipulated as objects, adding and removing rows and columns on-the-fly.
The new Fluid-based implementation is enabled by the global setting :php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['fluidBasedPageModule']`
which can be changed from the install tool or from extensions. The setting is enabled by default, meaning that the Fluid-based implementation is used
as default method in this and future TYPO3 versions.
The feature flag can be managed either by setting it through code (for example, in :file:`ext_localconf.php` of an extension) or you can set it through
the "Settings" admin module's' "Feature Toggles" view.
New Fluid templates:
* :file:`EXT:backend/Resources/Private/Templates/PageLayout/PageLayout.html`
* :file:`EXT:backend/Resources/Private/Templates/PageLayout/UnusedRecords.html`
* :file:`EXT:backend/Resources/Private/Partials/PageLayout/Grid.html`
* :file:`EXT:backend/Resources/Private/Partials/PageLayout/Grid/Column.html`
* :file:`EXT:backend/Resources/Private/Partials/PageLayout/Record.html`
* :file:`EXT:backend/Resources/Private/Partials/PageLayout/Record/Header.html`
* :file:`EXT:backend/Resources/Private/Partials/PageLayout/Record/Footer.html`
These Fluid templates can be overridden or extended by TS, depending on which type or types of templates you wish to override:
* :typoscript:`module.tx_backend.view.templateRootPaths.100 = EXT:myext/Resources/Private/Templates/`
* :typoscript:`module.tx_backend.view.partialRootPaths.100 = EXT:myext/Resources/Private/Partials/`
In addition, custom header/footer/preview templates can be added by extending the :typoscript:`partialRootPaths` and placing for example a template file in:
* :file:`EXT:myext/Resources/Private/Partials/PageLayout/Record/my_contenttype/Header`
* :file:`EXT:myext/Resources/Private/Partials/PageLayout/Record/my_contenttype/Footer`
* :file:`EXT:myext/Resources/Private/Partials/PageLayout/Record/my_contenttype/Preview`
If no such templates exist the default partials (listed above) are used. Note that the folder name :file:`my_contenttype`
should use the CType value associated with the content type for which you wish to provide a custom header, footer or preview template.
Within these last three types of templates the following variables are available:
* :html:`{item}` which represents a single record.
* :html:`{backendLayout}` which represents the :php:`BackendLayout` instance that defined the grid which was rendered.
* :html:`{grid}` which represents the :php:`Grid` instance that was produced by the :php:`BackendLayout`
(also accessible through :html:`{backendLayout.grid}`, provided as extracted variable for easier and more performance-efficient access)
Properties on :html:`{item}` include:
* :html:`{item.record}` (the database row of the content element)
* :html:`{item.column}` (the :php:`GridColumn` instance within which the item resides)
* :html:`{item.delible}`
* :html:`{item.translations}` (bool, whether or not the item is translated)
* :html:`{item.dragAndDropAllowed}` (bool, whether or not the item can be dragged and dropped)
* :html:`{item.footerInfo}` (array)
Properties on :html:`{backendLayout}` include:
* :html:`{backendLayout.configurationArray}` (array, the low level definition of rows/columns within the :php:`BackendLayout` - array form of the pageTSconfig that defines the grid)
* :html:`{backendLayout.iconPath}`
* :html:`{backendLayout.description}`
* :html:`{backendLayout.identifier}`
* :html:`{backendLayout.title}`
* :html:`{backendLayout.drawingConfiguration}` (the instance of :php:`DrawingConfiguration` which holds properties like active language, site languages and TCA labels for content types and content record fields)
* :html:`{backendLayout.grid}` (the instance of the :php:`Grid` that represents the backend layout rows/columns as PHP objects)
Impact
======
* A new feature setting :php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['fluidBasedPageModule']` has been introduced, enabled by default, which allows switching to the legacy :php:`PageLayoutView`.
* By default, a new set of objects and extended methods on :php:`BackendLayout` now provide a completely Fluid-based implementation of the "page" BE module.
.. index:: Backend, Fluid, ext:backend
@@ -0,0 +1,30 @@
.. include:: /Includes.rst.txt
.. _feature-90370:
=================================================================
Feature: #90370 - Use Egulias\EmailValidator for email validation
=================================================================
See :issue:`90370`
Description
===========
:php:`\TYPO3\CMS\Core\Utility\GeneralUtility::validEmail` now uses the package `Egulias\EmailValidator` and the `RFCValidation` for validating the provided email address.
This allows to follow the RFC more closely.
Impact
======
The following email addresses are now valid:
- `foo@äöüfoo.com`
- `foo@bar.123`
- `test@localhost`
- `äöüfoo@bar.com`
- `Abc@def"@example.com`
.. index:: PHP-API, ext:core
@@ -0,0 +1,53 @@
.. include:: /Includes.rst.txt
.. _feature-90411:
==========================================================================
Feature: #90411 - HTML-based workspace notification emails on stage change
==========================================================================
See :issue:`90411`
Description
===========
When inside workspaces, it is possible to notify affected (or all)
users belonging to that workspace by sending out an email when
items have been moved to the next stage in the workflow process.
These emails have been limited in the past due to marker-based templating and plain-text only.
The emails have been reworked and migrated to Fluid-based templated
emails, allowing for administrators to customize the contents of
those emails.
The following TSconfig options have been added:
.. code-block:: typoscript
# path where to look for templates / layouts / partials
tx_workspaces.emails.layoutRootPaths.100 = EXT:myproject/...
tx_workspaces.emails.partialRootPaths.100 = EXT:myproject/...
tx_workspaces.emails.templateRootPaths.100 = EXT:myproject/...
# valid formats are "text", "html" or "both"
tx_workspaces.emails.format = html
tx_workspaces.emails.senderEmail = workspaces@example.com
tx_workspaces.emails.senderName = Your TYPO3 at Example.com
The template name is always called `StageChangeNotification`.
It is still possible to use the existing plain-text variant
by setting the format to "text" and using the previous email
contents, if applicable. It is however recommended to make use
of the Fluid-based variables to make output more efficient.
The old TSconfig options have been superseded for defining the template via XLF labels.
Impact
======
Stage Change Notification emails are now sent as HTML+text by
default with the email template given in :file:`EXT:workspaces/Resources/Private/Templates/Emails/StageChangeNotification`.
.. index:: TSConfig, ext:workspaces
@@ -0,0 +1,46 @@
.. include:: /Includes.rst.txt
.. _feature-90416:
=============================================================================
Feature: #90416 - Specific target file extension in image-related ViewHelpers
=============================================================================
See :issue:`90416`
Description
===========
TYPO3 core's shipped Fluid ViewHelpers now allow to optionally
specify a target file extension via the new attribute `fileExtension`.
This affects the following ViewHelpers:
- :html:`<f:image>`
- :html:`<f:media>`
- :html:`<f:uri.image>`
This is rather important for specific scenarios where a :html:`<picture>` tag with multiple images are requested, allowing
to e.g. customize rendering for `webp` support, if the servers' ImageMagick version supports `webp` conversion.
In other regard, this might become useful to specify the output
for preview images of `pdf` files which can be converted via `GhostScript` if installed.
Impact
======
TYPO3 Integrators can now use the additional attribute
in their custom Fluid Templates for specific use cases.
Example:
.. code-block:: html
<picture>
<source srcset="{f:uri.image(image: fileObject, treatIdAsReference: true, fileExtension: 'webp')}" type="image/webp">
<source srcset="{f:uri.image(image: fileObject, treatIdAsReference: true, fileExtension: 'jpg')}" type="image/jpeg">
<f:image image="{fileObject}" treatIdAsReference="true" alt="{fileObject.alternative}" />
</picture>
.. index:: Fluid, ext:fluid
@@ -0,0 +1,23 @@
.. include:: /Includes.rst.txt
.. _feature-90425:
===============================================
Feature: #90425 - Add SEO fields to info module
===============================================
See :issue:`90425`
Description
===========
Two more options are added to the Info module (sub-module: "Pagetree Overview"):
"SEO" and "Social Media" to get a quick overview of the relevant data.
Impact
======
The options "SEO" and "Social Media" are added to the Pagetree Overview.
.. index:: Backend, TSConfig, ext:seo
@@ -0,0 +1,41 @@
.. include:: /Includes.rst.txt
.. _feature-90426:
========================================================
Feature: #90426 - Browser-native lazy loading for images
========================================================
See :issue:`90426`
Description
===========
TYPO3 now supports the browser-native :html:`loading` HTML attribute in :html:`<img>` tags.
It is set to "lazy" by default for all images within Content Elements rendered
with Fluid Styled Content. Supported browsers then choose to load these
images at a later point when the image is within the browsers' viewport.
The configuration option is available via TypoScript constants and
can be easily adjusted via the TypoScript Constant Editor in the Template module.
Please note that not all browsers support this option yet, but adding
this property will just be skipped for unsupported browsers.
Impact
======
TYPO3 Frontend now renders images in content elements with the :html:`"loading=lazy"`
attribute by default when using TYPO3's templates from Fluid Styled Content.
Using the TypoScript constant :typoscript:`styles.content.image.lazyLoading`,
the behavior can be modified generally to be either set to :html:`eager`,
:html:`auto` or to an empty value, removing the property directly.
The Fluid ImageViewHelper has the possibility to set this option
via :html:`<f:image src="{fileObject}" treatIdAsReference="true" loading="lazy" />`
to hint the browser on how the prioritization of image loading should be used.
.. index:: Frontend, ext:fluid_styled_content
@@ -0,0 +1,47 @@
.. include:: /Includes.rst.txt
.. _feature-90461:
===========================================================================
Feature: #90461 - Quick-Create Content Elements via NewContentElementWizard
===========================================================================
See :issue:`90461`
Description
===========
The new Content Element wizard within the Page Module now contains
an option called "saveAndClose" which directs a user back to the
Page Module directly instead of showing the FormEngine.
This is especially useful for custom content elements or container
content types where pre-defined values can be put in place directly,
saving editors one click on content creation.
The functionality is disabled by default, but explicitly enabled for the Content Type "divider".
Impact
======
This definition can be put into PageTSconfig (e.g. :file:`EXT:my_extension/Configuration/Page/main.tsconfig`) with the new flag "saveAndClose" enabled.
.. code-block:: typoscript
mod.wizards.newContentElement.wizardItems {
common.elements {
my_element {
iconIdentifier = content-my-icon
title = LLL:EXT:my_extension/Resources/Private/Language/ContentTypes.xlf:my_element_title
description = LLL:EXT:my_extension/Resources/Private/Language/ContentTypes.xlf:my_element_description
tt_content_defValues {
CType = my_element
header = Hello my friend
}
saveAndClose = 1
}
}
}
.. index:: Backend, TSConfig, ext:backend
@@ -0,0 +1,188 @@
.. include:: /Includes.rst.txt
.. _feature-90471:
======================================
Feature: #90471 - JavaScript Event API
======================================
See :issue:`90471`
Description
===========
A new Event API enables JavaScript developers to have a stable event listening
interface. The API takes care of common pitfalls like event delegation and clean
event unbinding.
Impact
======
Event Binding
-------------
Each event strategy (see below) has two ways to bind a listener to an event:
Direct Binding
^^^^^^^^^^^^^^
The event listener is bound to the element that triggers the event. This is done
by using the method :js:`bindTo()`, which accepts any element, :js:`document` and
:js:`window`.
Example:
.. code-block:: js
require(['TYPO3/CMS/Core/Event/RegularEvent'], function (RegularEvent) {
new RegularEvent('click', function (e) {
// Do something
}).bindTo(document.querySelector('#my-element'));
});
Event Delegation
^^^^^^^^^^^^^^^^
The event listener is called if the event was triggered to any matching element
inside its bound element.
Example:
.. code-block:: js
require(['TYPO3/CMS/Core/Event/RegularEvent'], function (RegularEvent) {
new RegularEvent('click', function (e) {
// Do something
}).delegateTo(document, 'a[data-action="toggle"]');
});
The event listener is now called every time the element matching the selector
:js:`a[data-action="toggle"]` within :js:`document` is clicked.
Release an event
^^^^^^^^^^^^^^^^
Since each event is an object instance, it's sufficient to call :js:`release()` to
detach the event listener.
Example:
.. code-block:: js
require(['TYPO3/CMS/Core/Event/RegularEvent'], function (RegularEvent) {
const clickEvent = new RegularEvent('click', function (e) {
// Do something
}).delegateTo(document, 'a[data-action="toggle"]');
// Do more stuff
clickEvent.release();
});
Event Strategies
----------------
The Event API brings several strategies to handle event listeners:
RegularEvent
^^^^^^^^^^^^
The :js:`RegularEvent` attaches a simple event listener to an event and element
and has no further tweaks. This is the common use-case for event handling.
Arguments:
* :js:`eventName` (string) - the event to listen on
* :js:`callback` (function) - the event listener
Example:
.. code-block:: js
require(['TYPO3/CMS/Core/Event/RegularEvent'], function (RegularEvent) {
new RegularEvent('click', function (e) {
e.preventDefault();
window.location.reload();
}).bindTo(document.querySelector('#my-element'));
});
DebounceEvent
^^^^^^^^^^^^^
The :js:`DebounceEvent` is most suitable if an event is triggered rather often
but executing the event listener may called only once after a certain wait time.
Arguments:
* :js:`eventName` (string) - the event to listen on
* :js:`callback` (function) - the event listener
* :js:`wait` (number) - the amount of milliseconds to wait before the event listener is called
* :js:`immediate` (boolean) - if true, the event listener is called right when the event started
Example:
.. code-block:: js
require(['TYPO3/CMS/Core/Event/DebounceEvent'], function (DebounceEvent) {
new DebounceEvent('mousewheel', function (e) {
console.log('Triggered once after 250ms!');
}, 250).bindTo(document);
});
ThrottleEvent
^^^^^^^^^^^^^
Arguments:
* :js:`eventName` (string) - the event to listen on
* :js:`callback` (function) - the event listener
* :js:`limit` (number) - the amount of milliseconds to wait before the event listener is called
The :js:`ThrottleEvent` is similar to the :js:`DebounceEvent`. The important
difference is that the event listener is called after the configured wait time
during the overall event time.
If an event time is about 2000ms and the wait time is configured to be 100ms,
the event listener gets called up to 20 times in total (2000 / 100).
Example:
.. code-block:: js
require(['TYPO3/CMS/Core/Event/ThrottleEvent'], function (ThrottleEvent) {
new ThrottleEvent('mousewheel', function (e) {
console.log('Triggered every 100ms!');
}, 100).bindTo(document);
});
RequestAnimationFrameEvent
^^^^^^^^^^^^^^^^^^^^^^^^^^
The :js:`RequestAnimationFrameEvent` binds its execution to the browser's
:js:`RequestAnimationFrame` API. It is suitable for event listeners that
manipulate the DOM.
Arguments:
* :js:`eventName` (string) - the event to listen on
* :js:`callback` (function) - the event listener
Example:
.. code-block:: js
require(['TYPO3/CMS/Core/Event/RequestAnimationFrameEvent'], function (RequestAnimationFrameEvent) {
new RequestAnimationFrameEvent('mousewheel', function (e) {
console.log('Triggered every 16ms (= 60 FPS)!');
});
});
.. index:: JavaScript, ext:core
@@ -0,0 +1,132 @@
.. include:: /Includes.rst.txt
.. _changelog-Feature-90522-IntroduceAssetCollector:
==========================================
Feature: #90522 - Introduce AssetCollector
==========================================
See :issue:`90522`
Description
===========
AssetCollector is a concept to allow custom CSS/JS code, inline or external, to be added multiple
times in e.g. a Fluid template (via :html:`<f:asset.script>` or :html:`<f:asset.css>` ViewHelpers) but only rendered once
in the output.
The :php:`priority` flag (default: :php:`false`) controls where the asset is included:
* JavaScript will be output inside :html:`<head>` (:php:`priority=true`) or at the bottom of the :html:`<body>` tag (:php:`priority=false`)
* CSS will always be output inside :html:`<head>`, yet grouped by :js:`priority`.
By including assets per-component, it can leverage the adoption of HTTP/2 multiplexing which removes the necessity of having all CSS/JavaScript
concatenated into one file.
AssetCollector is implemented as singleton and should slowly replace the various existing options
in TypoScript.
AssetCollector also collects information about "imagesOnPage", effectively taking off pressure from
PageRenderer and TSFE to store common data in FE - as this is now handled in AssetCollector,
which can be used in cached and non-cached components.
The new API
-----------
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::addJavaScript(string $identifier, string $source, array $attributes, array $options = []): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::addInlineJavaScript(string $identifier, string $source, array $attributes, array $options = []): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::addStyleSheet(string $identifier, string $source, array $attributes, array $options = []): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::addInlineStyleSheet(string $identifier, string $source, array $attributes, array $options = []): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::addMedia(string $fileName, array $additionalInformation): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::removeJavaScript(string $identifier): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::removeInlineJavaScript(string $identifier): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::removeStyleSheet(string $identifier): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::removeInlineStyleSheet(string $identifier): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::removeMedia(string $identifier): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::getJavaScripts(?bool $priority = null): array`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::getInlineJavaScripts(?bool $priority = null): array`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::getStyleSheets(?bool $priority = null): array`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::getInlineStyleSheets(?bool $priority = null): array`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::getMedia(): array`
New ViewHelpers
---------------
There are also two new ViewHelpers, the :html:`<f:asset.css>` and the - :html:`<f:asset.script>` ViewHelper which use the AssetCollector API.
.. code-block:: html
<f:asset.css identifier="identifier123" href="EXT:my_ext/Resources/Public/Css/foo.css" />
<f:asset.css identifier="identifier123">
.foo { color: black; }
</f:asset.css>
<f:asset.script identifier="identifier123" src="EXT:my_ext/Resources/Public/JavaScript/foo.js" />
<f:asset.script identifier="identifier123">
alert('hello world');
</f:asset.script>
Considerations
--------------
Currently, assets registered with the AssetCollector are not included in callbacks of these hooks:
- :php:`$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssCompressHandler']`
- :php:`$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsCompressHandler']`
- :php:`$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssConcatenateHandler']`
- :php:`$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsConcatenateHandler']`
.. versionadded:: 10.4
Events for the new API have been introduced in
:ref:`changelog-Feature-90899-IntroduceAssetPreRenderingEvents`
Currently, CSS and JavaScript registered with the AssetCollector will be rendered after their
PageRenderer counterparts. The order is:
- :html:`<head>`
- :typoscript:`page.includeJSLibs.forceOnTop`
- :typoscript:`page.includeJSLibs`
- :typoscript:`page.includeJS.forceOnTop`
- :typoscript:`page.includeJS`
- :php:`AssetCollector::addJavaScript()` with 'priority'
- :typoscript:`page.jsInline`
- :php:`AssetCollector::addInlineJavaScript()` with 'priority'
- :html:`</head>`
- :typoscript:`page.includeJSFooterlibs.forceOnTop`
- :typoscript:`page.includeJSFooterlibs`
- :typoscript:`page.includeJSFooter.forceOnTop`
- :typoscript:`page.includeJSFooter`
- :php:`AssetCollector::addJavaScript()`
- :typoscript:`page.jsFooterInline`
- :php:`AssetCollector::addInlineJavaScript()`
Currently, JavaScript registered with AssetCollector is not affected by
:typoscript:`config.moveJsFromHeaderToFooter`.
Examples
--------
Add a JavaScript file to the collector with script attribute data-foo="bar":
.. code-block:: php
GeneralUtility::makeInstance(AssetCollector::class)
->addJavaScript('my_ext_foo', 'EXT:my_ext/Resources/Public/JavaScript/foo.js', ['data-foo' => 'bar']);
Add a JavaScript file to the collector with script attribute :html:`data-foo="bar"` and priority which means rendering before other script tags:
.. code-block:: php
GeneralUtility::makeInstance(AssetCollector::class)
->addJavaScript('my_ext_foo', 'EXT:my_ext/Resources/Public/JavaScript/foo.js', ['data-foo' => 'bar'], ['priority' => true]);
Add a JavaScript file to the collector with :html:`type="module"` (by default, no type= is output for JavaScript):
.. code-block:: php
GeneralUtility::makeInstance(AssetCollector::class)
->addJavaScript('my_ext_foo', 'EXT:my_ext/Resources/Public/JavaScript/foo.js', ['type' => 'module']);
.. index:: Backend, Frontend, PHP-API, ext:core
@@ -0,0 +1,23 @@
.. include:: /Includes.rst.txt
.. _important-89672:
==============================================================================
Important: #89672 - transOrigPointerField is not longer allowed to be excluded
==============================================================================
See :issue:`89672`
Description
===========
The configured :php:`$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']`
can now not longer be excluded as this leads to inconsistent data stored in the
database. This happens when a non-admin user creates a localization by not having
the permission to edit the :php:`transOrigPointerField`. Usually this is the
:php:`l10n_parent` or :php:`l18n_parent` field.
A migration wizard is available that removes the option from your TCA and adds a
deprecation message to the deprecation log where code adaption has to take place.
.. index:: Backend, Database, TCA, ext:core
@@ -0,0 +1,25 @@
.. include:: /Includes.rst.txt
.. _important-89720:
====================================================================
Important: #89720 - Only TypoScript files loaded on directory import
====================================================================
See :issue:`89720`
Description
===========
With :issue:`82812` the new :typoscript:`@import` syntax for importing TypoScript has been added.
Among others the change was documented to only load :file:`*.typoscript` files in case a directory is imported. However, this was not implemented as such and all files where imported instead.
The code has been fixed to only load :file:`*.typoscript` files on directory import. To load other files besides :file:`*.typoscript` a suitable file pattern must be added explicitly now:
.. code-block:: typoscript
# Import TypoScript files with legacy ".txt" extension
@import 'EXT:myproject/Configuration/TypoScript/Setup/*.txt'
.. index:: TypoScript, ext:core
@@ -0,0 +1,27 @@
.. include:: /Includes.rst.txt
.. _important-89869:
===================================================================================
Important: #89869 - Change lockIP default to disabled for both frontend and backend
===================================================================================
See :issue:`89869`
Description
===========
The default setting for the lockIP settings has been changed to disabled. This affects the following four settings:
- FE->lockIP
- FE->lockIPv6
- BE->lockIP
- BE->lockIPv6
While the lockIP feature helps to protect user sessions in some scenarios, the feature also breaks many usage scenarios.
In particular the feature causes random session loss with IPv6 usage because of the Happy eyeballs/Fast fallback algorithm, which causes clients
with IPv6 and IPv4 address support to arbitrarily change between IPv4 and IPv6 based on which connection is established first.
Anyone considering re-enabling lockIP, should be be sure to evaluate any potential issues first, especially when using it with IPv6.
.. index:: Backend, Frontend
@@ -0,0 +1,32 @@
.. include:: /Includes.rst.txt
.. _important-89992:
==============================================
Important: #89992 - Use new Translation Server
==============================================
See :issue:`89992`
Description
===========
The work on the new translation server has been finalized so that it is used by default.
The SaaS solution Crowdin is being used to make it as simple as possible for everyone to improve the
localization of TYPO3 core and all extensions which are taking part.
If you are interested in improving the localization, register at https://crowdin.com/ and suggest translations at
the official TYPO3 Project, which can be found at https://crowdin.com/project/typo3-cms.
The documentation about the integration is part of the official TYPO3 documentation and
is available at https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/Internationalization/TranslationServer/Crowdin.html.
It also covers how to make your extension as extension developer available at Crowdin.
Impact
======
The feature switch :php:`betaTranslationServer`, introduced with :issue:`89526`,
has been removed and is not evaluated anymore.
.. index:: Backend, Frontend, ext:core
@@ -0,0 +1,20 @@
.. include:: /Includes.rst.txt
.. _important-90020:
==============================================================================================
Important: #90020 - Legacy BasicFileUtility and ExtendedFileUtility classes marked as internal
==============================================================================================
See :issue:`90020`
Description
===========
The two classes used to handle File permission and File upload logic - BasicFileUtility and ExtendedFileUtility -
have been marked as internal, as TYPO3 Core now fully relies on the File Abstraction Layer, which was introduced in TYPO3 v6.0.
The remaining parts are partially in use and will be phased out, for the time being all
extension authors should rely on :php:`ResourceStorage` and :php:`ResourceFactory` for managing assets.
.. index:: FAL, ext:core
@@ -0,0 +1,20 @@
.. include:: /Includes.rst.txt
.. _important-90236:
========================================================================================
Important: #90236 - Respect extension state 'excludeFromUpdates' during language updates
========================================================================================
See :issue:`90236`
Description
===========
If the state property inside :file:`ext_emconf.php` is set to `excludeFromUpdates`,
the extension will be skipped while updating the language files in the Install Tool.
This setting is especially helpful if you create a custom extension which uses the same extension
key as an existing TER extension.
.. index:: Backend, ext:core
@@ -0,0 +1,22 @@
.. include:: /Includes.rst.txt
.. _important-90371:
========================================================================================
Important: #90371 - TypoScript option config.content_from_pid_allowOutsideDomain removed
========================================================================================
See :issue:`90371`
Description
===========
TYPO3's Site Handling - introduced in TYPO3 v9 - allows defining
multiple sites within one installation, whereas before all configuration was based on domain records.
The TypoScript option :typoscript:`config.content_from_pid_allowOutsideDomain` was used to limit
the page property option "Show content from this page instead" (:typoscript:`pages.content_from_pid`) to be
evaluated outside of the current page tree which was ineffective since the usage of Site Handling.
The option serves no purpose anymore and has been removed.
.. index:: Frontend, TypoScript, ext:frontend
+53
View File
@@ -0,0 +1,53 @@
:template: changelogOverview.html
.. include:: /Includes.rst.txt
.. _changelog-10-3:
10.3 Changes
=============
**Table of contents**
.. contents::
:local:
:depth: 1
Breaking Changes
^^^^^^^^^^^^^^^^
None since TYPO3 v10.0 release.
.. attention::
After TYPO3 v10.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 v10.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-*