TYPO3 v15 dev-main snapshot ()
This commit is contained in:
+45
@@ -0,0 +1,45 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-100014-1677078784:
|
||||
|
||||
==========================================================================================
|
||||
Deprecation: #100014 - Function `getParameterFromUrl()` of `@typo3/backend/utility` module
|
||||
==========================================================================================
|
||||
|
||||
See :issue:`100014`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The function :js:`getParameterFromUrl()` of the :js:`@typo3/backend/utility`
|
||||
module was used to obtain a query string argument from an arbitrary URL.
|
||||
Meanwhile, browsers received the `URLSearchParams API`_ that can be used
|
||||
instead.
|
||||
|
||||
Therefore, :js:`getParameterFromUrl()` has been marked as deprecated.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Calling :js:`getParameterFromUrl()` will trigger a deprecation warning.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
All installations using third-party extensions relying on the deprecated code are
|
||||
affected.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
Migrate to the following snippet to get the same result:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
const paramValue = new URL(url, window.location.origin).searchParams.get(parameter);
|
||||
|
||||
.. _URLSearchParams API: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
|
||||
|
||||
.. index:: JavaScript, NotScanned, ext:backend
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-100033-1677433329:
|
||||
|
||||
============================================================
|
||||
Deprecation: #100033 - TBE_STYLES stylesheet and stylesheet2
|
||||
============================================================
|
||||
|
||||
See :issue:`100033`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The usage of :php:`$GLOBALS['TBE_STYLES']['stylesheet']` and
|
||||
:php:`$GLOBALS['TBE_STYLES']['stylesheet2']` to add custom CSS files
|
||||
to the TYPO3 backend has been marked as deprecated in TYPO3 v12 and will be
|
||||
removed in TYPO3 v13.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Using any of the following configuration declarations
|
||||
|
||||
* :php:`$GLOBALS['TBE_STYLES']['stylesheet']`
|
||||
* :php:`$GLOBALS['TBE_STYLES']['stylesheet2']`
|
||||
|
||||
will trigger a PHP deprecation notice and will throw a fatal PHP error in
|
||||
TYPO3 v13.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
The extension scanner will find extensions using
|
||||
|
||||
* :php:`$GLOBALS['TBE_STYLES']['stylesheet']`
|
||||
* :php:`$GLOBALS['TBE_STYLES']['stylesheet2']`
|
||||
|
||||
as "weak" matches.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
Extensions should use :php:`$GLOBALS['TYPO3_CONF_VARS']['BE']['stylesheets']['my_extension']`
|
||||
where :php:`'my_extension'` is the extension key.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. code-block:: php
|
||||
:caption: EXT:my_extension/ext_localconf.php
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS']['BE']['stylesheets']['my_extension'] = 'EXT:my_extension/Resources/Public/Css';
|
||||
|
||||
In the example above, all CSS files in the configured directory will be loaded
|
||||
in TYPO3 backend.
|
||||
|
||||
.. index:: Backend, FullyScanned, ext:backend
|
||||
@@ -0,0 +1,50 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-100047-1677607925:
|
||||
|
||||
==========================================================
|
||||
Deprecation: #100047 - Deprecated ConditionMatcher classes
|
||||
==========================================================
|
||||
|
||||
See :issue:`100047`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The following classes have been marked as deprecated in TYPO3 v12 and will
|
||||
be removed with v13:
|
||||
|
||||
* :php:`\TYPO3\CMS\Core\Configuration\TypoScript\ConditionMatching\ConditionMatcherInterface`
|
||||
* :php:`\TYPO3\CMS\Core\Configuration\TypoScript\ConditionMatching\AbstractConditionMatcher`
|
||||
* :php:`\TYPO3\CMS\Backend\Configuration\TypoScript\ConditionMatching\ConditionMatcher`
|
||||
* :php:`\TYPO3\CMS\Frontend\Configuration\TypoScript\ConditionMatching\ConditionMatcher`
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
The TYPO3 Core only uses these classes within the old TypoScript parser classes,
|
||||
which have been :ref:`deprecated <deprecation-99120-1670428555>` as well.
|
||||
Using the classes will trigger a deprecation level log entry.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
There was probably little need to implement new variants of the above classes as
|
||||
the underlying :php:`ExpressionLanguage` construct has its own API to add new
|
||||
variables and functions for this TypoScript condition related to Symfony expression
|
||||
language usage.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
No direct migration possible. These classes have been merged into the new
|
||||
TypoScript parser approach, specifically for class
|
||||
:php:`\TYPO3\CMS\Core\TypoScript\IncludeTree\Visitor\IncludeTreeConditionMatcherVisitor`.
|
||||
|
||||
Adding TypoScript related expression language variables and functions should be
|
||||
done using :php:`\TYPO3\CMS\Core\ExpressionLanguage\ProviderInterface`.
|
||||
|
||||
.. index:: PHP-API, FullyScanned, ext:core
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-100047-1677608959:
|
||||
|
||||
===============================================================================
|
||||
Deprecation: #100047 - Page TSconfig and user TSconfig must not rely on request
|
||||
===============================================================================
|
||||
|
||||
See :issue:`100047`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Using :typoscript:`request` and function :typoscript:`ip()` in page TSconfig or
|
||||
user TSconfig conditions has been marked as deprecated in TYPO3 v12. Such conditions
|
||||
will stop working in TYPO3 v13 and will always evaluate to false.
|
||||
|
||||
Page TSconfig and user TSconfig should not rely on request related data: They should
|
||||
not check for given arguments or similar: the main reason is that the Backend
|
||||
:php:`DataHandler` makes heavy use of page TSconfig, but the DataHandler itself is
|
||||
not request-aware. The DataHandler (the code logic that updates data in the database
|
||||
in the backend) can be used and must work in a CLI context, so any page TSconfig that
|
||||
depends on a given request is flawed by design since it will never act as expected
|
||||
in a CLI context.
|
||||
|
||||
To avoid further issues with the DataHandler in web and CLI contexts,
|
||||
TSconfig-related conditions must no longer be request-aware.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Using request-related conditions in page TSconfig or user TSconfig will raise a
|
||||
deprecation level warning in TYPO3 v12 and will always evaluate to false in
|
||||
TYPO3 v13.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
There may be instances of page TSconfig using conditions using
|
||||
request-related conditions. These need to look for different solutions
|
||||
that achieve a similar goal.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
Try to get rid of :typoscript:`ip()` or request related information in
|
||||
page TSconfig conditions.
|
||||
|
||||
A typical example is highlighting something when a developer is
|
||||
using the live domain:
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
[request.getRequestHost() == 'development.my.site']
|
||||
mod.foo = bar
|
||||
[end]
|
||||
|
||||
Switch to the application context in such cases:
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
[applicationContext == "Development"]
|
||||
mod.foo = bar
|
||||
[end]
|
||||
|
||||
There are similar alternatives for other use cases: You can not rely on given
|
||||
GET / POST arguments anymore, but it should be possible to switch to
|
||||
:typoscript:`backend.user.isAdmin` or similar conditions in most cases, or to
|
||||
handle related switches within controller classes in PHP.
|
||||
|
||||
Relying on request arguments for page TSconfig conditions is fiddly,
|
||||
especially when using this for core related controllers: those are not considered
|
||||
API and may change at anytime. Instead, needs should be dealt with explicitly using
|
||||
toggles within controllers.
|
||||
|
||||
|
||||
.. index:: TSConfig, NotScanned, ext:backend
|
||||
@@ -0,0 +1,67 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-100053-1677670333:
|
||||
|
||||
============================================
|
||||
Deprecation: #100053 - GeneralUtility::_GP()
|
||||
============================================
|
||||
|
||||
See :issue:`100053`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The method :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::_GP()` has
|
||||
been marked as deprecated and should not be used any longer.
|
||||
|
||||
Modern code should access GET and POST data from the PSR-7 :php:`ServerRequestInterface`,
|
||||
and should avoid accessing superglobals :php:`$_GET` and :php:`$_POST`
|
||||
directly. This also avoids future side-effects when using sub-requests. Some
|
||||
:php:`GeneralUtility` related helper methods like :php:`_GP()` violate this,
|
||||
using them is considered a technical debt. They are being phased out.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Calling the method from PHP code will log a PHP deprecation level entry,
|
||||
the method will be removed with TYPO3 v13.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
TYPO3 installations with third-party extensions using :php:`GeneralUtility::_GP()`
|
||||
are affected, typically in TYPO3 installations which
|
||||
have been migrated to the latest TYPO3 Core versions and
|
||||
haven't been adapted properly yet.
|
||||
|
||||
The extension scanner will find usages with a strong match.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
:php:`GeneralUtility::_GP()` is a helper method that retrieves
|
||||
incoming HTTP `GET` query arguments and `POST` body parameters and returns the value.
|
||||
|
||||
The same result can be achieved by retrieving arguments from the request object.
|
||||
An instance of the PSR-7 :php:`ServerRequestInterface` is handed over to
|
||||
controllers by TYPO3 Core's PSR-15 :php:`\TYPO3\CMS\Core\Http\RequestHandlerInterface`
|
||||
and middleware implementations, and is available in various related scopes
|
||||
like the frontend :php:`\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer`.
|
||||
|
||||
Typical code:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
// Before
|
||||
$value = GeneralUtility::_GP('tx_scheduler');
|
||||
|
||||
// After
|
||||
$value = $request->getParsedBody()['tx_scheduler'] ?? $request->getQueryParams()['tx_scheduler'] ?? null;
|
||||
|
||||
|
||||
.. index:: PHP-API, FullyScanned, ext:core
|
||||
@@ -0,0 +1,88 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-100071-1677853787:
|
||||
|
||||
========================================================
|
||||
Deprecation: #100071 - Magic repository findBy() methods
|
||||
========================================================
|
||||
|
||||
See :issue:`100071`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Extbase repositories come with a magic :php:`__call()` method to allow calling
|
||||
the following methods without implementing them:
|
||||
|
||||
- :php:`findBy[PropertyName]($propertyValue)`
|
||||
- :php:`findOneBy[PropertyName]($propertyValue)`
|
||||
- :php:`countBy[PropertyName]($propertyValue)`
|
||||
|
||||
These have now been marked as deprecated, as they are "magic", meaning
|
||||
that proper IDE support is not possible, and other PHP-related tool
|
||||
functionality such as PhpStorm.
|
||||
|
||||
In addition, it is not possible for Extbase repositories
|
||||
to build their own magic method functionality as the logic is already
|
||||
in use.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
As these methods are widely used in almost all Extbase-based extensions,
|
||||
they are marked as deprecated in TYPO3 v12, but will only trigger a deprecation
|
||||
notice in TYPO3 v13, as they will be removed in TYPO3 v14.
|
||||
|
||||
This way, migration towards the new API methods can be made without
|
||||
pressure.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
All installations with third-party extensions that use those magic methods.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
A new set of methods without all the downsides have been added:
|
||||
|
||||
- :php:`findBy(array $criteria, ...): QueryResultInterface`
|
||||
- :php:`findOneBy(array $criteria, ...):object|null`
|
||||
- :php:`count(array $criteria, ...): int`
|
||||
|
||||
The naming of the methods follows those of `doctrine/orm` and only
|
||||
:php:`count()` differs from the formerly :php:`countBy()`. While all magic
|
||||
methods only allow for a single comparison (`propertyName` = `propertyValue`),
|
||||
those methods allow for multiple comparisons, called constraints.
|
||||
|
||||
|
||||
`findBy[PropertyName]($propertyValue)` can be replaced with a call to `findBy`:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$this->blogRepository->findBy(['propertyName' => $propertyValue]);
|
||||
|
||||
|
||||
`findOneBy[PropertyName]($propertyValue)` can be replaced with a call to `findOneBy`:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$this->blogRepository->findOneBy(['propertyName' => $propertyValue]);
|
||||
|
||||
|
||||
`countBy[PropertyName]($propertyValue)` can be replaced with a call to `count`:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$this->blogRepository->count(['propertyName' => $propertyValue]);
|
||||
|
||||
.. attention::
|
||||
|
||||
Please note that the (not-magic) methods `findByUid()` and `findByIdentifier()` did **not**
|
||||
get deprecated or removed, and are still valid to be used.
|
||||
Using these methods will fetch a given domain object by it's UID, ignoring possible storage
|
||||
page settings - unlike `findBy([...])`, which does respect those settings.
|
||||
|
||||
.. index:: PHP-API, NotScanned, ext:extbase
|
||||
@@ -0,0 +1,60 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-100232-1679344508:
|
||||
|
||||
=========================================================
|
||||
Deprecation: #100232 - $TBE_STYLES skinning functionality
|
||||
=========================================================
|
||||
|
||||
See :issue:`100232`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The global configuration array :php:`$TBE_STYLES` has been deprecated in favor of a new
|
||||
setting :php:`$TYPO3_CONF_VARS['BE']['stylesheets']`. Previously, before
|
||||
TYPO3 v6.0, :php:`$TBE_STYLES` allowed for defining more styles within PHP instead
|
||||
of using CSS.
|
||||
However, now that CSS has become been much more powerful than 10 years ago,
|
||||
it is time to change the logic and also consolidate TYPO3's internal configuration
|
||||
settings.
|
||||
|
||||
This deprecation is in order to be more flexible for styling purposes, as
|
||||
the registration of custom stylesheets can now be handled on a per-project
|
||||
basis.
|
||||
|
||||
Extensions can use almost the same syntax, however registration is now done
|
||||
in an extension's :file:`ext_localconf.php` to reduce loading times for
|
||||
:file:`ext_tables.php` files.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Registration of backend styles via :php:`$GLOBALS['TBE_STYLES']['skins']` in
|
||||
an extension's :file:`ext_tables.php` file will trigger a PHP
|
||||
deprecation notice.
|
||||
|
||||
Setting :php:`$GLOBALS['TBE_STYLES']['stylesheets']['admPanel']` will also
|
||||
trigger a deprecation notice every time the Admin Panel is loaded in the
|
||||
TYPO3 frontend.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
TYPO3 installations with custom styling in the TYPO3 backend or the Admin Panel
|
||||
via :php:`$GLOBALS['TBE_STYLES']`.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
Migrate to the new configuration setting :php:`$GLOBALS['TYPO3_CONF_VARS']['BE']['stylesheets']`
|
||||
which can be set per site or within an extension's :file:`ext_localconf.php`.
|
||||
|
||||
For a custom stylesheet in the TYPO3 Admin Panel, it is recommended to use the
|
||||
new AdminPanel Module API (available since TYPO3 v9 LTS) where custom CSS and
|
||||
JavaScript files can be registered dynamically.
|
||||
|
||||
.. index:: Backend, LocalConfiguration, PHP-API, FullyScanned, ext:backend
|
||||
@@ -0,0 +1,58 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-100237-1679393509:
|
||||
|
||||
====================================================
|
||||
Deprecation: #100237 - TypoScript-related exceptions
|
||||
====================================================
|
||||
|
||||
See :issue:`100237`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Two exception classes related to the TypoScript condition matching logic have been
|
||||
marked as deprecated in TYPO3 v12 and will be removed in v13:
|
||||
|
||||
* :php:`\TYPO3\CMS\Core\Exception\MissingTsfeException`
|
||||
* :php:`\TYPO3\CMS\Core\Configuration\TypoScript\Exception\InvalidTypoScriptConditionException`
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Both exceptions should have been marked :php:`@internal` within the core, but
|
||||
were not.
|
||||
|
||||
The exception :php:`\TYPO3\CMS\Core\Exception\MissingTsfeException` was an internal
|
||||
communication class and was caught internally, the use case was solved in a more
|
||||
simple way avoiding the exception.
|
||||
|
||||
The exception :php:`\TYPO3\CMS\Core\Configuration\TypoScript\Exception\InvalidTypoScriptConditionException`
|
||||
was related to conditions which triggered a warning within the symfony expression language. Those were
|
||||
turned into this exception in TYPO3 v11. In TYPO3 v12, the original exception will bubble up, forcing
|
||||
developers to fix the broken Symfony condition syntax.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
Third-party extensions most likely neither throw nor catch these exceptions, the
|
||||
extension scanner will find possible usages.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
No direct migration available.
|
||||
|
||||
.. note::
|
||||
|
||||
Using the :typoscript:`getTSFE()` function, developers have to ensure
|
||||
that "TSFE" is available before accessing its properties. A missing "TSFE",
|
||||
e.g. in backend context, does no longer automatically evaluate the whole
|
||||
condition to :php:`FALSE`. Instead, the function returns :php:`NULL`,
|
||||
which can be checked using either :typoscript:`[getTSFE() && getTSFE().id == 42]`
|
||||
or the null-safe operator :typoscript:`[getTSFE()?.id == 42]`.
|
||||
|
||||
.. index:: PHP-API, FullyScanned, ext:core
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-100247-1679480707:
|
||||
|
||||
======================================================================
|
||||
Deprecation: #100247 - Various interconnected methods in EXT:scheduler
|
||||
======================================================================
|
||||
|
||||
See :issue:`100247`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The scheduler system extension, responsible for executing long-running, timed
|
||||
or recurring tasks, has been included since TYPO3 v4.3, but never received an
|
||||
overhaul of its code base.
|
||||
|
||||
Back then, the main :php:`\TYPO3\CMS\Scheduler\Scheduler` class and the
|
||||
:php:`\TYPO3\CMS\Scheduler\Task\AbstractTask` class were the main API classes, all logic being included,
|
||||
whereas :php:`AbstractTask` is the main class that all custom tasks within
|
||||
extensions derive from.
|
||||
|
||||
However, in the past 15 years TYPO3's code base has undergone a lot of API
|
||||
design changes related to separation of concerns. In order to achieve this in
|
||||
the scheduler extension, almost all access to the actual database access around
|
||||
task retrieving and scheduling has been moved into its own
|
||||
:php:`\TYPO3\CMS\Scheduler\Domain\Repository\SchedulerTaskRepository` class.
|
||||
|
||||
For this reason, the following methods within the original API classes are now
|
||||
either marked as deprecated or internal - not part of TYPO3's public API
|
||||
anymore - as they have now been moved into the new repository class.
|
||||
|
||||
* :php:`Scheduler->addTask()`
|
||||
* :php:`Scheduler->log()` - marked as internal
|
||||
* :php:`Scheduler->removeTask()`
|
||||
* :php:`Scheduler->saveTask()`
|
||||
* :php:`Scheduler->fetchTask()`
|
||||
* :php:`Scheduler->fetchTaskRecord()`
|
||||
* :php:`Scheduler->fetchTaskWithCondition()`
|
||||
* :php:`Scheduler->isValidTaskObject()`
|
||||
* :php:`Scheduler->log()` - marked as internal
|
||||
* :php:`AbstractTask->isExecutionRunning()`
|
||||
* :php:`AbstractTask->markExecution()`
|
||||
* :php:`AbstractTask->unmarkExecution()`
|
||||
* :php:`AbstractTask->unmarkAllExecutions()`
|
||||
* :php:`AbstractTask->save()` - marked as internal
|
||||
* :php:`AbstractTask->remove()`
|
||||
* :php:`AbstractTask->setScheduler()` - marked as internal
|
||||
* :php:`AbstractTask->unsetScheduler()` - marked as internal
|
||||
* :php:`AbstractTask->registerSingleExecution()` - marked as internal
|
||||
* :php:`AbstractTask->getExecution()` - marked as internal
|
||||
* :php:`AbstractTask->setExecution()` - marked as internal
|
||||
* :php:`AbstractTask->getNextDueExecution()` - marked as internal
|
||||
* :php:`AbstractTask->areMultipleExecutionsAllowed()` - marked as internal
|
||||
* :php:`AbstractTask->stop()` - marked as internal
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Calling any of the deprecated methods will trigger a PHP warning. Using the
|
||||
internal methods should be avoided and is not covered by the TYPO3 backwards
|
||||
compatibility promise.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
TYPO3 installations with extensions that include custom scheduler tasks accessing
|
||||
these methods. The Extension Scanner might be helpful to detect these usages.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
Use the :php:`SchedulerTaskRepository` methods instead.
|
||||
|
||||
.. index:: PHP-API, PartiallyScanned, ext:scheduler
|
||||
@@ -0,0 +1,41 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-100278-1679605129:
|
||||
|
||||
======================================================
|
||||
Deprecation: #100278 - PostLoginFailureProcessing hook
|
||||
======================================================
|
||||
|
||||
See :issue:`100278`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The hook :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['postLoginFailureProcessing']`
|
||||
which can be used to handle custom notifications that a login in a frontend or
|
||||
backend context failed, has been marked as deprecated.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
If the hook is registered in a TYPO3 installation, a PHP :php:`E_USER_DEPRECATED`
|
||||
error is triggered.
|
||||
|
||||
The extension scanner also detects any usage of the deprecated interface as
|
||||
a strong match, and the definition of the hook as a weak match.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
TYPO3 installations with custom extensions using this hook.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
Migrate to the newly introduced PSR-14 event
|
||||
:ref:`\\TYPO3\\CMS\\Core\\Authentication\\Event\\LoginAttemptFailedEvent <feature-100278-1679604666>`.
|
||||
|
||||
.. index:: Backend, Frontend, PHP-API, FullyScanned, ext:core
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-100307-1679924603:
|
||||
|
||||
====================================================================
|
||||
Deprecation: #100307 - Various hooks related to authentication users
|
||||
====================================================================
|
||||
|
||||
See :issue:`100307`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The following hooks have been marked as deprecated:
|
||||
|
||||
* :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing']`
|
||||
* :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_post_processing']`
|
||||
* :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['backendUserLogin']`
|
||||
|
||||
They can be used to add notifications or actions to a TYPO3 installation
|
||||
after a frontend user or a backend user has actively logged
|
||||
in or logged out.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
If one of the hooks is registered in a TYPO3 installation,
|
||||
a PHP :php:`E_USER_DEPRECATED` error is triggered when a user logs
|
||||
in or logs out.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
TYPO3 installations with custom extensions using one of these hooks.
|
||||
|
||||
The extension scanner detects any usage of the hooks.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
Migrate to the newly introduced PSR-14 events:
|
||||
|
||||
* :php:`\TYPO3\CMS\Core\Authentication\Event\BeforeUserLogoutEvent`
|
||||
* :php:`\TYPO3\CMS\Core\Authentication\Event\AfterUserLoggedOutEvent`
|
||||
* :php:`\TYPO3\CMS\Core\Authentication\Event\AfterUserLoggedInEvent`
|
||||
|
||||
.. seealso::
|
||||
:ref:`feature-100307-1679924551`
|
||||
|
||||
.. index:: Backend, Frontend, PHP-API, FullyScanned, ext:core
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-83608-1679521195:
|
||||
|
||||
================================================================
|
||||
Deprecation: #83608 - Backend user's getDefaultUploadFolder hook
|
||||
================================================================
|
||||
|
||||
See :issue:`83608`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The hook :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['getDefaultUploadFolder']` has been marked
|
||||
as deprecated in favor of a new PSR-14 event :php:`AfterDefaultUploadFolderWasResolvedEvent`.
|
||||
|
||||
Along with the hook, the two methods:
|
||||
|
||||
* :php:`BackendUserAuthentication->getDefaultUploadFolder()`
|
||||
* :php:`BackendUserAuthentication->getDefaultUploadTemporaryFolder()`
|
||||
|
||||
have been marked as internal, as they are not considered part of the public TYPO3 API anymore.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Using this hook will trigger a PHP deprecation notice every time the method
|
||||
:php:`BackendUserAuthentication->getDefaultUploadFolder()` is called,
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
TYPO3 installations with special functionality in extensions using these methods or the hook.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
Migrate to the PSR-14 event :ref:`AfterDefaultUploadFolderWasResolvedEvent <feature-83608-1669634686>`
|
||||
in your custom extensions.
|
||||
|
||||
It is fired after various page TSconfig settings have been applied and allows for more
|
||||
fine-grained control.
|
||||
|
||||
.. index:: Backend, PHP-API, FullyScanned, ext:backend
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-97390-1667657114:
|
||||
|
||||
=============================================================================
|
||||
Deprecation: #97390 - TypoScript validators for password reset in ext:felogin
|
||||
=============================================================================
|
||||
|
||||
See :issue:`97390`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The TypoScript password validation configured through
|
||||
:typoscript:`plugin.tx_felogin_login.settings.passwordValidators` has been
|
||||
marked as deprecated.
|
||||
|
||||
The TypoScript validators are used when the feature toggle
|
||||
`security.usePasswordPolicyForFrontendUsers` is set to `false` (default for
|
||||
existing TYPO3 installations).
|
||||
|
||||
An upgrade wizard will ask the user during the TYPO3 upgrade
|
||||
if `security.usePasswordPolicyForFrontendUsers` should be activated or, if
|
||||
deprecated, TypoScript validators should be used.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Validators configured in
|
||||
:typoscript:`plugin.tx_felogin_login.settings.passwordValidators` will
|
||||
trigger a deprecation log entry when a password reset is performed.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
TYPO3 installations using validators configured in
|
||||
:typoscript:`plugin.tx_felogin_login.settings.passwordValidators`.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
Special password requirements configured using custom validators in TypoScript
|
||||
must be migrated to a custom password policy validator as described
|
||||
in :ref:`#97388 <feature-97388>`.
|
||||
|
||||
Before creating a custom password policy validator, it is recommended to
|
||||
check if the :php:`CorePasswordValidator` used in the default password
|
||||
policy suits current password requirements.
|
||||
|
||||
.. index:: Frontend, NotScanned, ext:felogin
|
||||
@@ -0,0 +1,279 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-99739-1674869090:
|
||||
|
||||
======================================================
|
||||
Deprecation: #99739 - Indexed array keys for TCA items
|
||||
======================================================
|
||||
|
||||
See :issue:`99739`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Using indexed array keys for the :php:`items` configuration of TCA types
|
||||
:php:`select`, :php:`radio` and :php:`check` is now deprecated.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Using indexed array keys for the :php:`items` configuration array items of TCA
|
||||
types :php:`select`, :php:`radio` and :php:`check` will trigger a deprecation
|
||||
level log entry. A TCA migration is in place.
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
All installations having custom extensions that make use of TCA types
|
||||
:php:`select`, :php:`radio` or :php:`check` and define at least one entry in
|
||||
the :php:`items` array.
|
||||
|
||||
itemsProcFunc
|
||||
_____________
|
||||
|
||||
The :php:`items` array handed over to custom :php:`itemsProcFunc` functions
|
||||
contains the new object type :php:`TYPO3\CMS\Core\Schema\Struct\SelectionItem`
|
||||
which acts as a compatibility layer for old style indexed keys. Accessing,
|
||||
writing and reading items still work in the old way. Added items will be
|
||||
automatically converted. For third-party extensions supporting both TYPO3 v11
|
||||
(or lower) and v12 it is recommended to keep using indexed keys.
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
To migrate your TCA, change all indexed keys according to the following mapping
|
||||
table:
|
||||
|
||||
+--------+-------------+
|
||||
| Before | After |
|
||||
+--------+-------------+
|
||||
| 0 | label |
|
||||
+--------+-------------+
|
||||
| 1 | value |
|
||||
+--------+-------------+
|
||||
| 2 | icon |
|
||||
+--------+-------------+
|
||||
| 3 | group |
|
||||
+--------+-------------+
|
||||
| 4 | description |
|
||||
+--------+-------------+
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// Before
|
||||
'select' => [
|
||||
'label' => 'My select field',
|
||||
'config' => [
|
||||
'type' => 'select',
|
||||
'renderType' => 'selectSingle',
|
||||
'items' => [
|
||||
[
|
||||
'Selection 1',
|
||||
'1',
|
||||
'my-icon-identifier',
|
||||
'default',
|
||||
],
|
||||
[
|
||||
0 => 'Selection 2',
|
||||
1 => '2',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
// After
|
||||
'select' => [
|
||||
'label' => 'My select field',
|
||||
'config' => [
|
||||
'type' => 'select',
|
||||
'renderType' => 'selectSingle',
|
||||
'items' => [
|
||||
[
|
||||
'label' => 'Selection 1',
|
||||
'value' => '1',
|
||||
'icon' => 'my-icon-identifier',
|
||||
'group' => 'default',
|
||||
],
|
||||
[
|
||||
'label' => 'Selection 2',
|
||||
'value' => '2',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
// Before
|
||||
'select_checkbox' => [
|
||||
'label' => 'My select checkbox field',
|
||||
'config' => [
|
||||
'type' => 'select',
|
||||
'renderType' => 'selectCheckBox',
|
||||
'items' => [
|
||||
[
|
||||
'My select checkbox field',
|
||||
'1',
|
||||
'my-icon-identifier',
|
||||
'default',
|
||||
'My custom description',
|
||||
],
|
||||
[
|
||||
0 => 'My select checkbox field',
|
||||
1 => 'value' => '2',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
// After
|
||||
'select_checkbox' => [
|
||||
'label' => 'My select checkbox field',
|
||||
'config' => [
|
||||
'type' => 'select',
|
||||
'renderType' => 'selectCheckBox',
|
||||
'items' => [
|
||||
[
|
||||
'label' => 'My select checkbox field',
|
||||
'value' => '1',
|
||||
'icon' => 'my-icon-identifier',
|
||||
'group' => 'default',
|
||||
'description' => 'My custom description',
|
||||
],
|
||||
[
|
||||
'label' => 'My select checkbox field',
|
||||
'value' => '2',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
// Before
|
||||
'radio' => [
|
||||
'label => 'My radio field',
|
||||
'config' => [
|
||||
'type' => 'radio',
|
||||
'items' => [
|
||||
[
|
||||
'Radio 1',
|
||||
'1',
|
||||
],
|
||||
[
|
||||
0 => 'Radio 2',
|
||||
1 => '2',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
// After
|
||||
'radio' => [
|
||||
'label => 'My radio field',
|
||||
'config' => [
|
||||
'type' => 'radio',
|
||||
'items' => [
|
||||
[
|
||||
'label' => 'Radio 1',
|
||||
'value' => '1',
|
||||
],
|
||||
[
|
||||
'label' => 'Radio 2',
|
||||
'value' => '2',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
// Before
|
||||
'check' => [
|
||||
'config' => [
|
||||
'type' => 'check',
|
||||
'items' => [
|
||||
['Click on me'],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
// After
|
||||
'check' => [
|
||||
'config' => [
|
||||
'type' => 'check',
|
||||
'items' => [
|
||||
['label' => 'Click on me'],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
// Before
|
||||
'check' => [
|
||||
'config' => [
|
||||
'type' => 'check',
|
||||
'items' => [
|
||||
[
|
||||
'invertStateDisplay' => true,
|
||||
0 => 'Click on me',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
// After
|
||||
'check' => [
|
||||
'config' => [
|
||||
'type' => 'check',
|
||||
'items' => [
|
||||
[
|
||||
'invertStateDisplay' => true,
|
||||
'label' => 'Click on me',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
Before:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<select_single_1>
|
||||
<label>select_single_1 description</label>
|
||||
<description>field description</description>
|
||||
<config>
|
||||
<type>select</type>
|
||||
<renderType>selectSingle</renderType>
|
||||
<items>
|
||||
<numIndex index="0">
|
||||
<numIndex index="0">foo1</numIndex>
|
||||
<numIndex index="1">foo1</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="1">
|
||||
<numIndex index="0">foo2</numIndex>
|
||||
<numIndex index="1">foo2</numIndex>
|
||||
</numIndex>
|
||||
</items>
|
||||
</config>
|
||||
</select_single_1>
|
||||
|
||||
After:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<select_single_1>
|
||||
<label>select_single_1 description</label>
|
||||
<description>field description</description>
|
||||
<config>
|
||||
<type>select</type>
|
||||
<renderType>selectSingle</renderType>
|
||||
<items>
|
||||
<numIndex index="0">
|
||||
<label>foo1</label>
|
||||
<value>foo1</value>
|
||||
</numIndex>
|
||||
<numIndex index="1">
|
||||
<label>foo2</label>
|
||||
<value>foo2</value>
|
||||
</numIndex>
|
||||
</items>
|
||||
</config>
|
||||
</select_single_1>
|
||||
|
||||
.. index:: TCA, FullyScanned, ext:backend
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-99810-1675704638:
|
||||
|
||||
==================================================================
|
||||
Deprecation: #99810 - "versionNumberInFilename" option now boolean
|
||||
==================================================================
|
||||
|
||||
See :issue:`99810`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The system-wide setting :php:`$TYPO3_CONF_VARS['FE']['versionNumberInFilename']`
|
||||
was previously evaluated as a "string" value, having three possible options:
|
||||
|
||||
* ""
|
||||
* "querystring"
|
||||
* "embed"
|
||||
|
||||
Depending on the option, resources used in TYPO3's frontend templates, such as
|
||||
JavaScript or CSS assets, had their "modification time" in either the
|
||||
querystring (:samp:`myfile.js?1675703622`), or in the file name itself
|
||||
:samp:`myfile.1675703622.js` - the "embed" option). The latter option required a
|
||||
:file:`.htaccess` rule.
|
||||
|
||||
This existing feature ("cachebusting") is especially important for proxy / CDN
|
||||
setups.
|
||||
|
||||
For the sake of simplicity, the option is now a boolean option - and behaves
|
||||
similarly to the backend variant :php:`$TYPO3_CONF_VARS['BE']['versionNumberInFilename']`.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
If the option is now set to "false", it behaves as "querystring" did before, setting
|
||||
it to "true", the feature behaves exactly as "embed". The original empty option
|
||||
is removed, so all assets within the TYPO3 frontend rendering always include
|
||||
cachebusting, by default a querystring, which is fully backwards-compatible.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
TYPO3 installations that have actively set this option in
|
||||
:file:`LocalConfiguration.php`, :file:`AdditionalConfiguration.php` or in an
|
||||
extension :file:`ext_localconf.php`.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
When updating TYPO3 and accessing the maintenance area, an explicitly set option
|
||||
is automatically migrated. If this is not possible - for example, configuration in
|
||||
:file:`AdditionalConfiguration.php` is set - the value is always migrated
|
||||
on-the-fly when the setting is evaluated.
|
||||
|
||||
.. index:: LocalConfiguration, PHP-API, NotScanned, ext:core
|
||||
@@ -0,0 +1,65 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-99882-1675873624:
|
||||
|
||||
===========================================================
|
||||
Deprecation: #99882 - Site language "typo3Language" setting
|
||||
===========================================================
|
||||
|
||||
See :issue:`99882`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A language configuration defined for a site has had various settings, one of
|
||||
them being :yaml:`typo3Language`. The setting is used to define the language key which
|
||||
should be used for fetching the proper XLF file (such as :file:`de_AT.locallang.xlf`).
|
||||
|
||||
Since TYPO3 v12 it is unnecessary to set this property in the site configuration
|
||||
and it is removed from the backend UI. The information is now automatically
|
||||
derived from the :yaml:`locale` setting of the site configuration.
|
||||
|
||||
The previous value "default", which matched "en" as language key is now unnecessary
|
||||
as "default" is now a synonym for "en".
|
||||
|
||||
As a result, the amount of options in the user interface for integrators is
|
||||
reduced.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
An administrator cannot select a value for the :yaml:`typo3Language` setting anymore
|
||||
via the TYPO3 backend. If a custom value is required, the site configuration
|
||||
needs to be manually edited and the :yaml:`typo3Language` setting needs to be added.
|
||||
|
||||
If this is the case, please file a bug report in order to give the TYPO3
|
||||
development team feedback on what use case is required.
|
||||
|
||||
However, saving a site configuration via the TYPO3 backend will still
|
||||
keep the :yaml:`typo3Language` setting so no values will be lost.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
TYPO3 installations created before TYPO3 v12.3.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
No migration is needed as the explicit option is still evaluated. It is however
|
||||
recommended to check if the setting is really necessary.
|
||||
|
||||
Examples:
|
||||
|
||||
#. If :yaml:`typo3Language: "default"` and :yaml:`locale: "en_US.UTF-8"`, the setting can be removed.
|
||||
#. If :yaml:`typo3Language: "pt_BR"` and :yaml:`locale: "pt_BR.UTF-8"`, the setting can be removed.
|
||||
#. If :yaml:`typo3Language: "de"` and :yaml:`locale: "de_AT.UTF-8"` , the setting can be removed,
|
||||
plus the label files check for :file:`de_AT.locallang.xlf` and :file:`de.locallang.xlf`
|
||||
as fallback when accessing a translated label.
|
||||
#. If :yaml:`typo3Language: "pt_BR"` and :yaml:`locale: "de_DE.UTF-8"` it is likely
|
||||
a misconfiguration in the setup, and should be analyzed if the custom value is really needed.
|
||||
|
||||
.. index:: YAML, NotScanned, ext:core
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-99900-1676292952:
|
||||
|
||||
======================================================================
|
||||
Deprecation: #99900 - $limit parameter of GeneralUtility::intExplode()
|
||||
======================================================================
|
||||
|
||||
See :issue:`99900`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The static method :php:`GeneralUtility::intExplode()` has a lesser known fourth
|
||||
parameter :php:`$limit`. The reason it was added to the :php:`intExplode()` method
|
||||
is purely historical, when it used to extend the :php:`trimExplode()` method. The
|
||||
dependency was resolved, but the parameter stayed. As this method is supposed to
|
||||
only return :php:`int` values in an array, the :php:`$limit` parameter is now
|
||||
deprecated.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Calling :php:`GeneralUtility::intExplode()` with the fourth parameter
|
||||
:php:`$limit` will trigger a deprecation warning and will add an entry to the
|
||||
deprecation log.
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
TYPO3 installations that call :php:`GeneralUtility::intExplode()` with the
|
||||
fourth parameter :php:`$limit`.
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
In the rare case that you are using the :php:`$limit` parameter you will need to
|
||||
switch to PHP's native :php:`explode()` function, and then use
|
||||
:php:`array_map()` to convert the resulting array to integers. If that's
|
||||
impractical, you can simply copy the old :php:`intExplode` method to your own
|
||||
code.
|
||||
|
||||
.. index:: PHP-API, FullyScanned, ext:core
|
||||
@@ -0,0 +1,68 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-99905-1675963182:
|
||||
|
||||
=======================================================
|
||||
Deprecation: #99905 - Site language "iso-639-1" setting
|
||||
=======================================================
|
||||
|
||||
See :issue:`99905`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A language configuration defined for a site has had various settings, one of
|
||||
them being :yaml:`iso-639-1` (also known as "twoLetterIsoCode").
|
||||
|
||||
This setting was previously introduced to define the current ISO 639-1 code, which
|
||||
was different from the :yaml:`locale` or the :yaml:`typo3Language` setting. However,
|
||||
this information is now properly retrieved with the method:
|
||||
:php:`SiteLanguage->getLocale()->getLanguageCode()`.
|
||||
|
||||
Since TYPO3 v12 it is not necessary to set this property in the site configuration
|
||||
anymore, and it has been removed from the backend UI. The information is now automatically
|
||||
derived from the :yaml:`locale` setting of the site configuration.
|
||||
|
||||
This property originally came from an option in TypoScript called
|
||||
:typoscript:`config.sys_language_isocode` which in turn was created in favor of
|
||||
the previous :sql:`sys_language` database table. The TYPO3 Core never evaluated this
|
||||
setting properly before TYPO3 v9.
|
||||
|
||||
As a result, the amount of options in the user interface for integrators is
|
||||
reduced.
|
||||
|
||||
The PHP method :php:`SiteLanguage->getTwoLetterIsoCode()` serves no purpose
|
||||
anymore and is deprecated.
|
||||
|
||||
This also affects the TypoScript :typoscript:`getData` property :typoscript:`siteLanguage:twoLetterIsoCode`,
|
||||
and the TypoScript condition :typoscript:`[siteLanguage("twoLetterIsoCode")]`.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Using the TypoScript settings or the PHP method will trigger a PHP deprecation notice.
|
||||
|
||||
An administrator cannot select a value for the :yaml:`iso-639-1` setting anymore
|
||||
via the TYPO3 backend. However, saving a site configuration via the
|
||||
TYPO3 backend will still keep the :yaml:`iso-639-1` setting so no information is lost.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
TYPO3 installations actively accessing this property via PHP or TypoScript.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
No migration is needed as the explicit option is still evaluated. It is however
|
||||
recommended to check if the setting is really necessary, and if the first part of the
|
||||
:yaml:`locale` setting matches the :yaml:`iso-639-1` setting. If so, the line with
|
||||
:yaml:`iso-639-1` can be removed.
|
||||
|
||||
As for TypoScript, it is recommended to use :typoscript:`siteLanguage:locale:languageCode`
|
||||
instead of :typoscript:`siteLanguage:twoLetterIsoCode`.
|
||||
|
||||
.. index:: PHP-API, TypoScript, YAML, PartiallyScanned, ext:frontend
|
||||
@@ -0,0 +1,61 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-99908-1675976983:
|
||||
|
||||
======================================================
|
||||
Deprecation: #99908 - Site language "hreflang" setting
|
||||
======================================================
|
||||
|
||||
See :issue:`99908`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A language configuration defined for a site has had various settings, one of
|
||||
them being :yaml:`hreflang`. The setting is used to generate hreflang meta tags to
|
||||
link to alternative language versions of a translated page, and to add the
|
||||
:html:`lang` attribute to the :html:`<html>` tag of a frontend page in HTML format.
|
||||
|
||||
Since TYPO3 v12 it is not necessary to set this property in the site configuration
|
||||
anymore. The information is now automatically
|
||||
derived from the :yaml:`locale` setting of the site configuration if not set
|
||||
in the site configuration.
|
||||
|
||||
This also affects the TypoScript :typoscript:`getData` property
|
||||
:typoscript:`siteLanguage:hrefLang`, and the TypoScript condition
|
||||
:typoscript:`[siteLanguage("hrefLang")]`.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Using the TypoScript settings or the PHP method will trigger a PHP deprecation
|
||||
notice.
|
||||
|
||||
An administrator cannot select a value for the :yaml:`hreflang` setting anymore
|
||||
via the TYPO3 backend. However, when saving a site configuration via the
|
||||
TYPO3 backend it will still keep the :yaml:`hreflang` setting so no information is lost.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
TYPO3 installations actively accessing this property via PHP or TypoScript.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
No migration is needed as the explicit option is still evaluated. It is however
|
||||
recommended to check if the setting is really necessary, and if the locale of
|
||||
the site language in the :file:`config.yaml` matches the same value - even in a
|
||||
different format (:yaml:`locale: "de_AT.UTF-8"`, :yaml:`hreflang: "de-AT"`) - the setting
|
||||
:yaml:`hreflang` can be removed.
|
||||
|
||||
Any calls to :php:`SiteLanguage->getHrefLang()` can be replaced by
|
||||
:php:`SiteLanguage->getLocale()->getName()`.
|
||||
|
||||
As for TypoScript, it is recommended to use :typoscript:`siteLanguage:locale:full`
|
||||
instead of :typoscript:`siteLanguage:hrefLang`.
|
||||
|
||||
.. index:: Frontend, PHP-API, TypoScript, YAML, PartiallyScanned, ext:core
|
||||
@@ -0,0 +1,66 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-99916-1676027922:
|
||||
|
||||
=======================================================
|
||||
Deprecation: #99916 - Site language "direction" setting
|
||||
=======================================================
|
||||
|
||||
See :issue:`99916`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A language configuration defined for a site has had various settings, one of
|
||||
them being :yaml:`direction`. The setting is used to add the :html:`dir` attribute to the
|
||||
:html:`<html>` tag of a frontend page in HTML format, defining the direction of the
|
||||
language.
|
||||
|
||||
However, according to https://meta.wikimedia.org/wiki/Template:List_of_language_names_ordered_by_code
|
||||
the list of languages that have a directionality of "right-to-left"
|
||||
is fixed and does not need to be configured anymore.
|
||||
|
||||
Since TYPO3 v12 it is not necessary to set this property in the site configuration
|
||||
anymore, and has been removed from the backend UI. The information is now automatically
|
||||
derived from the :yaml:`locale` setting of the site configuration.
|
||||
|
||||
As a result, the amount of options in the user interface for integrators is
|
||||
reduced.
|
||||
|
||||
The PHP method :php:`SiteLanguage->getDirection()` serves no purpose anymore and
|
||||
is deprecated.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Using the PHP method will trigger a PHP deprecation notice.
|
||||
|
||||
An administrator can not select a value for the :yaml:`direction` setting anymore
|
||||
via the TYPO3 backend. However, when saving a site configuration via the
|
||||
TYPO3 backend it will still keep the :yaml:`direction` setting so no information is lost.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
TYPO3 installations actively accessing this property via PHP or TypoScript, and
|
||||
mainly related to TYPO3 installations with languages that have a "right-to-left"
|
||||
reading direction.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
No migration is needed as the explicit option is still evaluated. It is however
|
||||
not necessary in 99.99% of the use cases. If the locale of the site language in the
|
||||
site's :file:`config.yaml` matches the natural direction of the language
|
||||
(Arabic and direction = rtl), the setting :yaml:`direction` can be removed.
|
||||
|
||||
Any calls to :php:`SiteLanguage->getDirection()` can be replaced by
|
||||
:php:`SiteLanguage->getLocale()->isRightToLeftLanguageDirection() ? 'rtl' : 'ltr'`.
|
||||
|
||||
The frontend output does not set :html:`ltr` in the :html:`<html>` tag anymore, as this is the default
|
||||
for HTML documents (see https://www.w3.org/International/questions/qa-html-dir).
|
||||
|
||||
.. index:: PHP-API, YAML, FullyScanned, ext:core
|
||||
@@ -0,0 +1,43 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-99932-1676186779:
|
||||
|
||||
================================================================
|
||||
Deprecation: #99932 - PageRenderer::removeLineBreaksFromTemplate
|
||||
================================================================
|
||||
|
||||
See :issue:`99932`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The following method has been marked as deprecated and will be removed
|
||||
in TYPO3 v13:
|
||||
|
||||
* :php:`\TYPO3\CMS\Core\Page\PageRenderer::enableDebugMode()`
|
||||
|
||||
The method acts as as shortcut to quickly disable some functions in the backend
|
||||
context to ease output inspection. However, the properties set by the
|
||||
method are ignored in the backend context anyway, the method is obsolete.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Using the method will raise a deprecation level log entry and will stop
|
||||
working in TYPO3 v13.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
Instances with extensions that call the method are affected.
|
||||
|
||||
The extension scanner reports usages as a weak match.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
All calls to the deprecated messages should be removed from the codebase.
|
||||
|
||||
.. index:: Backend, TCA, FullyScanned, ext:core
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100027-1677251094:
|
||||
|
||||
=======================================================================
|
||||
Feature: #100027 - Copy files and folders within the File > List module
|
||||
=======================================================================
|
||||
|
||||
See :issue:`100027`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
With TYPO3 v12.2, the feature to
|
||||
:ref:`drag+drop files and folders <feature-99733-1675025218>` between the tree
|
||||
structure was added. Now it is also possible to copy or move resources within
|
||||
the actual file listing (tile view or list view), for example, into a different subfolder
|
||||
by selecting them, and using the mouse to drop them on to a target folder.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
The :guilabel:`File > List` module is now fully usable with drag+drop between
|
||||
the tree and within the listing itself.
|
||||
|
||||
All features make it easier for editors to manage and organize the digital
|
||||
assets used within TYPO3.
|
||||
|
||||
.. index:: Backend, ext:filelist
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100071-1677853567:
|
||||
|
||||
==============================================================
|
||||
Feature: #100071 - Introduce non-magic repository find methods
|
||||
==============================================================
|
||||
|
||||
See :issue:`100071`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Extbase repositories come with a magic :php:`__call()` method to allow calling
|
||||
the following methods without implementing:
|
||||
|
||||
- :php:`findBy[PropertyName]($propertyValue)`
|
||||
- :php:`findOneBy[PropertyName]($propertyValue)`
|
||||
- :php:`countBy[PropertyName]($propertyValue)`
|
||||
|
||||
Magic methods are quite handy but they have a huge disadvantage. There is no
|
||||
proper IDE support i.e. most IDEs show an error or at least a warning,
|
||||
saying method :php:`findByAuthor()` does not exist. Also, type declarations are
|
||||
impossible to use because with :php:`__call()` everything is :php:`mixed`. And
|
||||
last but not least, static code analysis - like PHPStan - cannot properly
|
||||
analyze those and give meaningful errors.
|
||||
|
||||
Therefore, there is a new set of methods without all those downsides:
|
||||
|
||||
- :php:`findBy(array $criteria, ...): QueryResultInterface`
|
||||
- :php:`findOneBy(array $criteria, ...): object|null`
|
||||
- :php:`count(array $criteria, ...): int`
|
||||
|
||||
The naming of those methods follows those of `doctrine/orm` and only
|
||||
:php:`count()` differs from the formerly :php:`countBy()`. While all magic
|
||||
methods only allow for a single comparison (`propertyName` = `propertyValue`),
|
||||
those methods allow for multiple comparisons, called constraints.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$this->blogRepository->findBy(['author' => 1, 'published' => true]);
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
The new methods support a broader feature set, support IDEs, static code
|
||||
analyzers and type declarations.
|
||||
|
||||
.. index:: PHP-API, NotScanned, ext:extbase
|
||||
@@ -0,0 +1,58 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100088-1677965005:
|
||||
|
||||
======================================
|
||||
Feature: #100088 - New TCA type "json"
|
||||
======================================
|
||||
|
||||
See :issue:`100088`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
In our effort of introducing dedicated TCA types for special use cases,
|
||||
a new TCA field type called :php:`json` has been added to TYPO3 Core.
|
||||
Its main purpose is to simplify the TCA configuration when working with
|
||||
fields, containing JSON data. It therefore :ref:`replaces <important-100088-1677950866>`
|
||||
the previously introduced :php:`dbtype=json` of TCA type :php:`user`.
|
||||
|
||||
Using the new type, TYPO3 automatically takes care of adding the corresponding
|
||||
database column.
|
||||
|
||||
The TCA type :php:`json` features the following column configuration:
|
||||
|
||||
- :php:`behaviour`: :php:`allowLanguageSynchronization`
|
||||
- :php:`cols`
|
||||
- :php:`default`
|
||||
- :php:`enableCodeEditor`
|
||||
- :php:`fieldControl`
|
||||
- :php:`fieldInformation`
|
||||
- :php:`fieldWizard`
|
||||
- :php:`placeholder`
|
||||
- :php:`readOnly`
|
||||
- :php:`required`
|
||||
- :php:`rows`
|
||||
|
||||
.. note::
|
||||
|
||||
In case :php:`enableCodeEditor` is set to :php:`true`, which is the default
|
||||
and the system extension `t3editor` is installed and active, the JSON value
|
||||
is rendered in the corresponding code editor. Otherwise it is rendered in a
|
||||
standard `textarea` HTML element.
|
||||
|
||||
The following column configuration can be overwritten by page TSconfig:
|
||||
|
||||
- :typoscript:`cols`
|
||||
- :typoscript:`rows`
|
||||
- :typoscript:`readOnly`
|
||||
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
It is now possible to use a dedicated TCA type for rendering of JSON fields.
|
||||
Using the new TCA type, corresponding database columns are added automatically.
|
||||
|
||||
.. index:: Backend, PHP-API, TCA, ext:backend
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100089-1677961107:
|
||||
|
||||
================================================================
|
||||
Feature: #100089 - Introduce Doctrine DBAL v3 driver middlewares
|
||||
================================================================
|
||||
|
||||
See :issue:`100089`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Since v3, Doctrine DBAL supports adding custom driver middlewares. These
|
||||
middlewares act as a decorator around the actual `Driver` component.
|
||||
Subsequently, the `Connection`, `Statement` and `Result` components can be
|
||||
decorated as well. These middlewares must implement the
|
||||
:php:`\Doctrine\DBAL\Driver\Middleware` interface.
|
||||
A common use case would be a middleware for implementing SQL logging capabilities.
|
||||
|
||||
For more information on driver middlewares,
|
||||
see https://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/architecture.html.
|
||||
Furthermore, you can look up the implementation of the
|
||||
:php:`\TYPO3\CMS\Adminpanel\Log\DoctrineSqlLoggingMiddleware` in ext:adminpanel
|
||||
as an example.
|
||||
|
||||
Registering a new driver middleware
|
||||
===================================
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['driverMiddlewares']['adminpanel_loggingmiddleware']
|
||||
= \TYPO3\CMS\Adminpanel\Log\DoctrineSqlLoggingMiddleware::class;
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Using custom middlewares allows to enhance the functionality of Doctrine
|
||||
components.
|
||||
|
||||
.. index:: Database, ext:core
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100093-1678091347:
|
||||
|
||||
=================================================================
|
||||
Feature: #100093 - Show path to record location in group elements
|
||||
=================================================================
|
||||
|
||||
See :issue:`100093`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
To ease the usage of `group` fields in the FormEngine, for example, like in the
|
||||
"Insert records" content element, the record overview now shows the path to the
|
||||
location where each assigned record is stored, respectively.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Elements of type `group` now show the path to the page where any assigned record
|
||||
is stored in.
|
||||
|
||||
.. index:: Backend, ext:backend
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100116-1678299307:
|
||||
|
||||
============================================================================
|
||||
Feature: #100116 - Make PSR-7 request accessible for authentication services
|
||||
============================================================================
|
||||
|
||||
See :issue:`100116`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Authentication services can now access the PSR-7 request object via the
|
||||
:php:`$authInfo` array. Previously, custom TYPO3 authentication services
|
||||
did not have direct access to the object and therefore had to either
|
||||
use PHP super globals or TYPO3's `GeneralUtility::getIndpEnv()` method.
|
||||
|
||||
The following example shows how to retrieve the PSR-7 request in the
|
||||
`initAuth()` method of a custom authentication service:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public function initAuth($mode, $loginData, $authInfo, $pObj)
|
||||
{
|
||||
/** @var ServerRequestInterface $request */
|
||||
$request = $authInfo['request'];
|
||||
|
||||
/** @var NormalizedParams $normalizedParams */
|
||||
$normalizedParams = $request->getAttribute('normalizedParams');
|
||||
$isHttps = $normalizedParams->isHttps();
|
||||
}
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Custom TYPO3 authentication services can now directly access the PSR-7
|
||||
request object from the authentication process. It is available via the
|
||||
:php:`request` key of the :php:`$authInfo` array, which is handed over
|
||||
to the :php:`initAuth()` method.
|
||||
|
||||
.. index:: ext:core
|
||||
@@ -0,0 +1,59 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100143-1678575248:
|
||||
|
||||
==================================================================
|
||||
Feature: #100143 - Add scheduler command to execute and list tasks
|
||||
==================================================================
|
||||
|
||||
See :issue:`100143`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The CLI command :bash:`scheduler:run` of EXT:scheduler offers a way to run a
|
||||
task using a cronjob. It also allows to run tasks if the UID of the task
|
||||
is known.
|
||||
|
||||
To make it more convenient to use the command, :bash:`scheduler:list` and
|
||||
:bash:`scheduler:execute` were introduced.
|
||||
|
||||
The :bash:`scheduler:list` command shows an overview of all available tasks or
|
||||
a given group with an option to watch and reload the list every X seconds
|
||||
(default every 1 second).
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# List all tasks in group 1 and group 2 and watch for changes every second.
|
||||
vendor/bin/typo3 scheduler:list --group 1 --group 2 --watch
|
||||
|
||||
# List all tasks without a group and watch for changes every 2 seconds.
|
||||
vendor/bin/typo3 scheduler:list --group 0 --watch 2
|
||||
|
||||
# Same as above with shortcut parameter
|
||||
vendor/bin/typo3 scheduler:list -g 0 -w 2
|
||||
|
||||
|
||||
The :bash:`scheduler:execute` command displays a list of groups and available
|
||||
tasks for the selection. If a group is selected all tasks within this group are
|
||||
executed.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Run alls tasks without a group and task 8
|
||||
vendor/bin/typo3 scheduler:execute --task g:0 --task 8
|
||||
|
||||
# Same as above with shortcut parameter
|
||||
vendor/bin/typo3 scheduler:execute -t g:0 -t 8
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
The new commands :bash:`scheduler:list` and :bash:`scheduler:execute` enable
|
||||
the user to manage and run tasks without leaving the terminal.
|
||||
|
||||
.. index:: Backend, ext:scheduler
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100167-1679005733:
|
||||
|
||||
====================================================================
|
||||
Feature: #100167 - AdminPanel: Add SQL and memory metrics to toolbar
|
||||
====================================================================
|
||||
|
||||
See :issue:`100167`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
This extends the AdminPanel toolbar with more metrics:
|
||||
|
||||
* Peak memory usage
|
||||
* Amount of SQL queries
|
||||
* Time spent processing SQL queries
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
The AdminPanel toolbar now shows more information.
|
||||
|
||||
.. index:: Frontend, ext:adminpanel
|
||||
@@ -0,0 +1,65 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100171-1678869689:
|
||||
|
||||
==========================================
|
||||
Feature: #100171 - Introduce TCA type uuid
|
||||
==========================================
|
||||
|
||||
See :issue:`100171`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
In our effort of introducing dedicated TCA types for special use cases,
|
||||
a new TCA field type called :php:`uuid` has been added to TYPO3 Core.
|
||||
Its main purpose is to simplify the TCA configuration when working with
|
||||
fields, containing a UUID.
|
||||
|
||||
The TCA type :php:`uuid` features the following column configuration:
|
||||
|
||||
- :php:`enableCopyToClipboard`
|
||||
- :php:`fieldInformation`
|
||||
- :php:`required`: Defaults to :php:`true`
|
||||
- :php:`size`
|
||||
- :php:`version`
|
||||
|
||||
.. note::
|
||||
|
||||
In case :php:`enableCopyToClipboard` is set to :php:`true`, which is the
|
||||
default, a button is rendered next to the input field, which allows to copy
|
||||
the UUID to the clipboard of the operating system.
|
||||
|
||||
.. note::
|
||||
|
||||
The :php:`version` option defines the UUID version to be used. Allowed
|
||||
values are `4`, `6` or `7`. The default is `4`. For more information
|
||||
about the different versions, have a look at the corresponding
|
||||
`symfony documentation`_.
|
||||
|
||||
The following column configuration can be overwritten by page TSconfig:
|
||||
|
||||
- :typoscript:`size`
|
||||
- :typoscript:`enableCopyToClipboard`
|
||||
|
||||
An example configuration looks like the following:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
'identifier' => [
|
||||
'label' => 'My record identifier',
|
||||
'config' => [
|
||||
'type' => 'uuid',
|
||||
'version' => 6,
|
||||
],
|
||||
],
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
It is now possible to use a dedicated TCA type for rendering of a UUID field.
|
||||
Using the new TCA type, corresponding database columns are added automatically.
|
||||
|
||||
.. _symfony documentation: https://symfony.com/doc/current/components/uid.html#uuids
|
||||
|
||||
.. index:: Backend, TCA, ext:backend
|
||||
@@ -0,0 +1,97 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100187-1679001588:
|
||||
|
||||
=====================================================
|
||||
Feature: #100187 - ICU-based date and time formatting
|
||||
=====================================================
|
||||
|
||||
See :issue:`100187`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
TYPO3 now supports rendering date and time based on formats/patterns defined by
|
||||
the International Components for Unicode standard (ICU).
|
||||
|
||||
TYPO3 previously only supported rendering of dates based on the PHP-native
|
||||
functions :php:`date()` and :php:`strftime()`.
|
||||
|
||||
However, :php:`date()` can only format dates with English texts, such as
|
||||
"December" as non-localized values, the C-based :php:`strftime()` function works
|
||||
only with the locale defined in PHP and availability in the underlying operating
|
||||
system.
|
||||
|
||||
In addition, ICU-based date and time formatting is much more flexible in
|
||||
rendering, as it ships with default patterns for date and time (namely
|
||||
`FULL`, `LONG`, `MEDIUM` and `SHORT`) which are based on the given locale.
|
||||
|
||||
This means, that when the locale `en-US` is given, the short date is rendered
|
||||
as `mm/dd/yyyy` whereas `de-AT` uses the `dd.mm.yyyy` syntax automatically,
|
||||
without having to define a custom pattern just by using the SHORT default
|
||||
pattern.
|
||||
|
||||
In addition, the patterns can be adjusted more fine-grained, and can easily
|
||||
deal with time zones for output when DateTime objects are handed in.
|
||||
|
||||
TYPO3 also adds prepared custom patterns:
|
||||
|
||||
* `FULLDATE` (like `FULL`, but only the date information)
|
||||
* `FULLTIME` (like `FULL`, but only the time information)
|
||||
* `LONGDATE` (like `LONG`, but only the date information)
|
||||
* `LONGTIME` (like `LONG`, but only the time information)
|
||||
* `MEDIUMDATE` (like `MEDIUM`, but only the date information)
|
||||
* `MEDIUMTIME` (like `MEDIUM`, but only the time information)
|
||||
* `SHORTDATE` (like `SHORT`, but only the date information)
|
||||
* `SHORTTIME` (like `SHORT`, but only the time information)
|
||||
|
||||
See https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax
|
||||
for more information on the patterns.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
A new stdWrap feature called `formattedDate` is added, and the new formatting
|
||||
can also be used in Fluid's :html:`<f:format.date>` ViewHelper.
|
||||
|
||||
The locale is typically fetched from the locale of the site language (stdWrap or
|
||||
ViewHelper), or the backend user's language (in backend context) for the
|
||||
ViewHelper usages.
|
||||
|
||||
Examples for stdWrap:
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
page.10 = TEXT
|
||||
page.10.value = 1998-02-20 3:00:00
|
||||
# see all available options https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax
|
||||
page.10.formattedDate = FULL
|
||||
# optional, if a different locale is wanted other than the Site Language's locale
|
||||
page.10.formattedDate.locale = de-DE
|
||||
|
||||
will result in "Freitag, 20. Februar 1998 um 03:00:00 Koordinierte Weltzeit".
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
page.10 = TEXT
|
||||
page.10.value = -5 days
|
||||
page.10.formattedDate = FULL
|
||||
page.10.formattedDate.locale = fr-FR
|
||||
|
||||
will result in "jeudi 9 mars 2023 à 21:40:49 temps universel coordonné".
|
||||
|
||||
Examples for Fluid `<f:format.date>` ViewHelper:
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<f:format.date pattern="dd. MMMM yyyy" locale="de-DE">{date}</f:format.date>
|
||||
|
||||
will result in "20. Februar 1998".
|
||||
|
||||
As soon as the :html:`pattern` attribute is used, the :html:`format` attribute
|
||||
is disregarded.
|
||||
|
||||
Both new ViewHelper arguments are optional.
|
||||
|
||||
.. index:: Fluid, PHP-API, TypoScript, ext:core
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100206-1679299435:
|
||||
|
||||
======================================================================
|
||||
Feature: #100206 - Enable list/tile view for resources in link browser
|
||||
======================================================================
|
||||
|
||||
See :issue:`100206`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
With this change, we are rolling out the universal file-list
|
||||
rendering for files and folders to the link browser. The link
|
||||
browser implementation for files and folders is now part of the
|
||||
filelist extension.
|
||||
|
||||
The link browser now allows the user to choose the display type
|
||||
of resources to match the personal preference between list and
|
||||
tile rendering.
|
||||
|
||||
When the user now edits a link for a folder, the entry point is
|
||||
the parent folder of the selected element folder instead of
|
||||
showing the contents of the selected resource. The user sees
|
||||
the selected folder in the presented list, this behavior mimics
|
||||
the handling of selected files.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
The user is now presented a unified experience when handling
|
||||
resources. The modern filelist rendering is now rolled out to
|
||||
the link browser and now covers, the filelist module, element
|
||||
browser and link browser.
|
||||
|
||||
.. index:: Backend, FAL, RTE, ext:filelist
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100218-1679312518:
|
||||
|
||||
================================================================
|
||||
Feature: #100218 - Improved TypoScript and page TSconfig modules
|
||||
================================================================
|
||||
|
||||
See :issue:`100218`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
TYPO3 v12 comes with a rewritten TypoScript syntax parser.
|
||||
See :ref:`breaking-97816-1656350406` and :ref:`feature-97816-1656350667`
|
||||
for more details on this.
|
||||
|
||||
The new parser allowed us to refactor the related backend modules along the way:
|
||||
While many of these have been done with earlier v12 releases already, v12.3 now
|
||||
finishes the basic feature set of these new and refactored modules.
|
||||
|
||||
This is a summary of these UI changes:
|
||||
|
||||
Frontend TypoScript
|
||||
-------------------
|
||||
|
||||
* The well-known main module :guilabel:`Web > Template` has been renamed and moved,
|
||||
and can be found as :guilabel:`Site Management > TypoScript`.
|
||||
|
||||
* "TypoScript records overview": This submodule was more hidden in previous versions.
|
||||
It gives an overview which page records have TypoScript template records.
|
||||
|
||||
* "Constant Editor": This submodule is mainly kept as-is from previous versions.
|
||||
|
||||
* "Edit TypoScript Record": This submodule was known as "Info / Modify" from previous
|
||||
versions. Its main functionality is kept.
|
||||
|
||||
* "Active TypoScript": This submodule was known as "TypoScript Object Browser" in
|
||||
previous versions. The UI of this module received a major streamlining and gives
|
||||
a better overview of the compiled TypoScript on a page: The module now shows
|
||||
both "constants" and "setup" at the same time, gives more detail information,
|
||||
and the tree is quicker to navigate.
|
||||
|
||||
* "Included TypoScript": This submodule was known as "Template Analyzer" in
|
||||
previous versions. Similar to "Active TypoScript", it shows "constants" and
|
||||
"setup" at the same time. It allows to simulate the effect of conditions
|
||||
to the include tree, and shows sub-includes from :typoscript:`@import` and
|
||||
similar as nodes within the tree. A basic syntax scanner finds broken TypoScript
|
||||
syntax snippets.
|
||||
|
||||
|
||||
Page TSconfig
|
||||
-------------
|
||||
|
||||
* The previous submodule :guilabel:`Web > Info > Page TSconfig` has been heavily refactored
|
||||
and can be found as new main module :guilabel:`Site Management > Page TSconfig`.
|
||||
|
||||
* The new page TSconfig module is similar in its look and feel to the TypoScript
|
||||
module.
|
||||
|
||||
* "Page TSconfig Records": This submodule did not exist as such in previous versions
|
||||
and gives an overview which page records in the system contain page TSconfig settings.
|
||||
|
||||
* "Active Page TSconfig": This is similar to "Active TypoScript" from the "TypoScript"
|
||||
module. It allows browsing current page TSconfig and allows simulating the effect
|
||||
of conditions.
|
||||
|
||||
* "Included page TSconfig": This is similar to the "Included TypoScript" from the
|
||||
"TypoScript" module. It shows all source files and records that create the final
|
||||
page TSconfig of a page. A basic syntax scanner finds broken syntax snippets.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
The refactored modules allow more fine grained analysis
|
||||
of page TSconfig and TypoScript.
|
||||
|
||||
.. index:: Backend, TSConfig, TypoScript, ext:backend
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100232-1679344020:
|
||||
|
||||
===============================================================
|
||||
Feature: #100232 - Load additional stylesheets in TYPO3 backend
|
||||
===============================================================
|
||||
|
||||
See :issue:`100232`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
It is now possible to load additional CSS files for the TYPO3
|
||||
backend interface via regular :php:`$TYPO3_CONF_VARS` settings in a
|
||||
:file:`settings.php` file of a project (previously known as :file:`LocalConfiguration.php`)
|
||||
file or in an extension's :file:`ext_localconf.php`.
|
||||
|
||||
Previously this was done via the outdated :php:`$TBE_STYLES`
|
||||
global array which has been deprecated.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
By defining a specific stylesheet, a single CSS file or all CSS files
|
||||
of a folder, extension authors can now modify the styling via:
|
||||
|
||||
.. code-block:: php
|
||||
:caption: EXT:my_extension/ext_localconf.php
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS']['BE']['stylesheets'][my_extension]
|
||||
= 'EXT:myextension/Resources/Public/Css/myfile.css';
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS']['BE']['stylesheets'][my_extension]
|
||||
= 'EXT:myextension/Resources/Public/Css/';
|
||||
|
||||
in their extension's :file:`ext_localconf.php` file.
|
||||
|
||||
Site administrators can handle this in their :php:`settings.php` or :php:`additional.php` file.
|
||||
|
||||
.. index:: LocalConfiguration, ext:backend
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100278-1679604666:
|
||||
|
||||
================================================================================
|
||||
Feature: #100278 - PSR-14 Event after failed logins in backend or frontend users
|
||||
================================================================================
|
||||
|
||||
See :issue:`100278`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A new PSR-14 event :php:`\TYPO3\CMS\Core\Authentication\Event\LoginAttemptFailedEvent`
|
||||
has been introduced. The event allows to notify remote systems about failed logins.
|
||||
|
||||
The event features the following methods:
|
||||
|
||||
- :php:`isFrontendAttempt()`: Whether this was a login attempt from a frontend login form
|
||||
- :php:`isBackendAttempt()`: Whether this was a login attempt in the backend
|
||||
- :php:`getUser()`: Returns the :php:`\TYPO3\CMS\Core\Authentication\AbstractUserAuthentication` derivative in question
|
||||
- :php:`getRequest()`: Returns the current PSR-7 request object
|
||||
- :php:`getLoginData()`: The attempted login data without sensitive information
|
||||
|
||||
Registration of the event in your extension's :file:`Services.yaml`:
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: EXT:my_extension/Configuration/Services.yaml
|
||||
|
||||
MyVendor\MyExtension\Authentication\EventListener\MyEventListener:
|
||||
tags:
|
||||
- name: event.listener
|
||||
identifier: 'my-extension/login-attempt-failed'
|
||||
|
||||
The corresponding event listener class:
|
||||
|
||||
.. code-block:: php
|
||||
:caption: EXT:my_extension/Classes/Authentication/EventListener/MyEventListener.php
|
||||
|
||||
namespace MyVendor\MyExtension\Authentication\EventListener;
|
||||
|
||||
use TYPO3\CMS\Core\Authentication\Event\LoginAttemptFailedEvent;
|
||||
|
||||
final class MyEventListener
|
||||
{
|
||||
public function __invoke(LoginAttemptFailedEvent $event): void
|
||||
{
|
||||
if ($event->getRequest()->getAttribute('normalizedParams')->getRemoteAddress() !== '198.51.100.42') {
|
||||
// send an email because an external user login attempt failed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
It is now possible to notify external loggers about failed login attempts
|
||||
while having the full request.
|
||||
|
||||
.. index:: Backend, Frontend, PHP-API, ext:core
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100284-1679681558:
|
||||
|
||||
===============================================================
|
||||
Feature: #100284 - Add CKEditor Inspector for backend RTE forms
|
||||
===============================================================
|
||||
|
||||
See :issue:`100284`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
This feature introduces the ability to show the CKEditor Inspector for backend RTE forms.
|
||||
|
||||
With CKEditor 5 and the introduction of the intermediate CKEditor model, knowing
|
||||
the internals is a requirement to build plugins. The best way to debug during the plugin
|
||||
development is the `CKEditor Inspector <https://ckeditor.com/docs/ckeditor5/latest/framework/development-tools.html#ckeditor-5-inspector>`_.
|
||||
|
||||
For regular pages, there is a simple bookmarklet that can be included to show
|
||||
the Inspector, but in the TYPO3 backend the usage of frames does not allow this
|
||||
option. Giving developers a config option in the RTE simplifies this process.
|
||||
|
||||
The Inspector can be activated in two different ways:
|
||||
|
||||
* By enabling :php:`$GLOBALS['TYPO3_CONF_VARS']['BE']['debug']` and
|
||||
being in the `Development` context
|
||||
* By setting the option :yaml:`editor.config.debug` to :yaml:`true` in your
|
||||
CKEditor configuration
|
||||
|
||||
Example for setting the CKEditor configuration:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
editor:
|
||||
config:
|
||||
debug: true
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Being in the right context or enabling the given option, it is now possible
|
||||
to debug CKEditor instances for plugin development in an easier way.
|
||||
|
||||
.. index:: Backend, RTE, YAML, ext:rte_ckeditor
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100293-1679673289:
|
||||
|
||||
================================================================
|
||||
Feature: #100293 - New ContentObject EXTBASEPLUGIN in TypoScript
|
||||
================================================================
|
||||
|
||||
See :issue:`100293`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
In order to lower the barrier for newcomers in the TYPO3 world, TYPO3 now has
|
||||
a custom ContentObject in TypoScript called :typoscript:`EXTBASEPLUGIN`.
|
||||
|
||||
Previously, TypoScript code for Extbase plugins looked like this:
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
page.10 = USER
|
||||
page.10 {
|
||||
userFunc = TYPO3\\CMS\\Extbase\\Core\\Bootstrap->run
|
||||
extensionName = shop
|
||||
pluginName = cart
|
||||
}
|
||||
|
||||
The new way, which Extbase plugin registration uses under the hood now, looks
|
||||
like this:
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
page.10 = EXTBASEPLUGIN
|
||||
page.10.extensionName = shop
|
||||
page.10.pluginName = cart
|
||||
|
||||
The old way still works, but it is recommended to use the :typoscript:`EXTBASEPLUGIN`
|
||||
ContentObject, as the direct reference to a PHP class (Bootstrap) might be
|
||||
optimized in future versions.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
This change is an effort to distinguish between plugins and regular other
|
||||
more static content.
|
||||
|
||||
Extbase is the de-facto standard for plugins, which serve dynamic content by
|
||||
custom PHP code divided in controllers and actions by extension developers.
|
||||
|
||||
Regular other content can be written in pure TypoScript, such as ContentObjects
|
||||
like FLUIDTEMPLATE, HMENU, COA or TEXT is used for other kind of renderings
|
||||
in the frontend.
|
||||
|
||||
.. index:: TypoScript, ext:extbase
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100294-1679766730:
|
||||
|
||||
=============================================================================
|
||||
Feature: #100294 - Add PSR-14 event to enrich password validation ContextData
|
||||
=============================================================================
|
||||
|
||||
See :issue:`100294`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A new PSR-14 event :php:`\TYPO3\CMS\Core\PasswordPolicy\Event\EnrichPasswordValidationContextDataEvent`
|
||||
has been added, which allows extension authors to enrich the
|
||||
:php:`\TYPO3\CMS\Core\PasswordPolicy\Validator\Dto\ContextData`
|
||||
DTO used in password policy validation.
|
||||
|
||||
The PSR-14 event is dispatched in all classes, where a user password is
|
||||
validated against the globally configured password policy.
|
||||
|
||||
The event features the following methods:
|
||||
|
||||
- :php:`getContextData()` returns the current :php:`ContextData` DTO
|
||||
- :php:`getUserData()` returns an array with user data available from the
|
||||
initiating class
|
||||
- :php:`getInitiatingClass()` returns the class name, where the
|
||||
:php:`ContextData` DTO is created
|
||||
|
||||
The event can be used to enrich the :php:`ContextData` DTO with additional data
|
||||
used in custom password policy validators.
|
||||
|
||||
.. note::
|
||||
|
||||
The user data returned by :php:`getUserData()` will include user data
|
||||
available from the initiating class only. Therefore, event listeners should
|
||||
always consider the initiating class name when accessing data from
|
||||
:php:`getUserData()`. If required user data is not available via
|
||||
:php:`getUserData()`, it can possibly be retrieved by a custom database
|
||||
query (e.g. data from user table in the password reset process by fetching
|
||||
the user with the :php:`uid` given in :php:`getUserData()` array).
|
||||
|
||||
Registration of the event in your extension's :file:`Services.yaml`:
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: EXT:my_extension/Configuration/Services.yaml
|
||||
|
||||
MyVendor\MyExtension\PasswordPolicy\EventListener\MyEventListener:
|
||||
tags:
|
||||
- name: event.listener
|
||||
identifier: 'my-extension/enrich-context-data'
|
||||
|
||||
The corresponding event listener class:
|
||||
|
||||
.. code-block:: php
|
||||
:caption: EXT:my_extension/Classes/PasswordPolicy/EventListener/MyEventListener.php
|
||||
|
||||
use TYPO3\CMS\Core\DataHandling\DataHandler;
|
||||
use TYPO3\CMS\Core\PasswordPolicy\Event\EnrichPasswordValidationContextDataEvent;
|
||||
|
||||
final class MyEventListener
|
||||
{
|
||||
public function __invoke(EnrichPasswordValidationContextDataEvent $event): void
|
||||
{
|
||||
if ($event->getInitiatingClass() === DataHandler::class) {
|
||||
$event->getContextData()->setData('currentMiddleName', $event->getUserData()['middle_name'] ?? '');
|
||||
$event->getContextData()->setData('currentEmail', $event->getUserData()['email'] ?? '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
With the new :php:`EnrichPasswordValidationContextDataEvent`, it is now
|
||||
possible to enrich the :php:`ContextData` DTO used in password policy
|
||||
validation with additional data.
|
||||
|
||||
.. index:: ext:core
|
||||
@@ -0,0 +1,78 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100307-1679924551:
|
||||
|
||||
========================================================
|
||||
Feature: #100307 - PSR-14 events for user login & logout
|
||||
========================================================
|
||||
|
||||
See :issue:`100307`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Three new PSR-14 events have been added:
|
||||
|
||||
- :php:`\TYPO3\CMS\Core\Authentication\Event\BeforeUserLogoutEvent`
|
||||
- :php:`\TYPO3\CMS\Core\Authentication\Event\AfterUserLoggedOutEvent`
|
||||
- :php:`\TYPO3\CMS\Core\Authentication\Event\AfterUserLoggedInEvent`
|
||||
|
||||
The purpose of these events is to trigger any kind of action when a user
|
||||
has been successfully logged in or logged out.
|
||||
|
||||
TYPO3 Core itself uses :php:`AfterUserLoggedInEvent` in the TYPO3 backend
|
||||
to send an email to a user, if the login was successful.
|
||||
|
||||
The event features the following methods:
|
||||
|
||||
- :php:`getUser()`: Returns the :php:`\TYPO3\CMS\Core\Authentication\AbstractUserAuthentication` derivative in question
|
||||
|
||||
The PSR-14 event :php:`BeforeUserLogoutEvent` on top has the possibility
|
||||
to bypass the regular logout process by TYPO3 (removing the cookie and
|
||||
the user session) by calling :php:`$event->disableRegularLogoutProcess()`
|
||||
in an event listener.
|
||||
|
||||
The PSR-14 event :php:`AfterUserLoggedInEvent` contains the method
|
||||
:php:`getRequest()` to return PSR-7 request object of the current request.
|
||||
|
||||
Registration of the event in your extension's :file:`Services.yaml`:
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: EXT:my_extension/Configuration/Services.yaml
|
||||
|
||||
MyVendor\MyExtension\Authentication\EventListener\MyEventListener:
|
||||
tags:
|
||||
- name: event.listener
|
||||
identifier: 'my-extension/after-user-logged-in'
|
||||
|
||||
The corresponding event listener class for :php:`AfterUserLoggedInEvent`:
|
||||
|
||||
.. code-block:: php
|
||||
:caption: EXT:my_extension/Classes/Authentication/EventListener/MyEventListener.php
|
||||
|
||||
namespace MyVendor\MyExtension\Authentication\EventListener;
|
||||
|
||||
use TYPO3\CMS\Core\Authentication\Event\AfterUserLoggedInEvent;
|
||||
|
||||
final class MyEventListener
|
||||
{
|
||||
public function __invoke(AfterUserLoggedInEvent $event): void
|
||||
{
|
||||
if (
|
||||
$event->getUser() instanceof BackendUserAuthentication
|
||||
&& $event->getUser()->isAdmin()
|
||||
)
|
||||
{
|
||||
// Do something like: Clear all caches after login
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
It is now possible to modify and adapt user functionality based on successful
|
||||
login or active logout.
|
||||
|
||||
.. index:: Backend, Frontend, PHP-API, ext:core
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-19856-1679091117:
|
||||
|
||||
=============================================================================
|
||||
Feature: #19856 - Set special ATagParams for links to access restricted pages
|
||||
=============================================================================
|
||||
|
||||
See :issue:`19856`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A new TypoScript option is introduced which allows additional tag attributes to be set
|
||||
to links of pages which are access restricted by frontend user group
|
||||
restriction. Usually these links will not be generated, but it is possible to
|
||||
link them to another page, for example, a special login page:
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
config.typolinkLinkAccessRestrictedPages = 13
|
||||
config.typolinkLinkAccessRestrictedPages_addParams = &originalPage=###PAGE_ID###
|
||||
|
||||
The resulting link to an access-restricted page (e.g. `22`) looks like this:
|
||||
:html:`<a href="/login?originalPage=22">My page</a>`
|
||||
|
||||
The newly introduced option
|
||||
:typoscript:`config.typolinkLinkAccessRestrictedPages.ATagParams` allows
|
||||
custom attributes to be added to the current anchor tag.
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
config.typolinkLinkAccessRestrictedPages.ATagParams = class="restricted"
|
||||
|
||||
This will result in
|
||||
:html:`<a href="/login?originalPage=22" class="restricted">My page</a>`.
|
||||
|
||||
When generating menus via HMENU, the new :typoscript:`ATagParams` option is
|
||||
also available for custom settings:
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
page.10 = HMENU
|
||||
page.10.showAccessRestrictedPages = 13
|
||||
page.10.showAccessRestrictedPages.ATagParams = class="access-restricted"
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Allowing integrators to set custom :typoscript:`ATagParams` such as class attributes or
|
||||
arbitrary data attributes to use client-side styling via CSS or JavaScript event
|
||||
listeners to handle such links differently.
|
||||
|
||||
.. index:: TypoScript, ext:frontend
|
||||
@@ -0,0 +1,49 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-45039-1674297405:
|
||||
|
||||
===========================================================
|
||||
Feature: #45039 - Command to clean up local processed files
|
||||
===========================================================
|
||||
|
||||
See :issue:`45039`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
It is now possible to set up a recurring scheduler task or execute a CLI command
|
||||
to clean up locally processed files and their database records.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
The command will delete :sql:`sys_file_processedfile` records with references to
|
||||
non-existing files. Also, files in the configured temporary directory
|
||||
(typically :file:`_processed_`) will be deleted if there are no references to them.
|
||||
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
Delete files and records with confirmation:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./bin/typo3 cleanup:localprocessedfiles
|
||||
|
||||
Delete files and records:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./bin/typo3 cleanup:localprocessedfiles -f
|
||||
|
||||
Only show which files and records would be deleted:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./bin/typo3 cleanup:localprocessedfiles --dry-run -v
|
||||
|
||||
Please note that the command currently only works for local drivers.
|
||||
|
||||
.. index:: CLI, PHP-API, ext:lowlevel
|
||||
@@ -0,0 +1,37 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-65020-1679498591:
|
||||
|
||||
===========================================================
|
||||
Feature: #65020 - Change button labels within TCA type=file
|
||||
===========================================================
|
||||
|
||||
See :issue:`65020`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
When working with file references (:sql:`sys_file_reference` records) within FormEngine,
|
||||
there are up to three buttons available:
|
||||
|
||||
* "Create new relation"
|
||||
* "Select & upload files"
|
||||
* "Add media by URL"
|
||||
|
||||
Whereas the first button text can be changed via TCA on a per-field basis via
|
||||
:php:`[config][appearance][createNewRelationLinkTitle] = 'LLL:my_extension/...';`
|
||||
the two other label fields are hard-coded. It is especially useful to override such a label
|
||||
when only a certain type of media is required (for example, just images) or online media of type YouTube.
|
||||
|
||||
It is now possible to do so by using two new TCA configuration settings for TCA type=file
|
||||
|
||||
* :php:`[config][appearance][uploadFilesLinkTitle]`
|
||||
* :php:`[config][appearance][addMediaLinkTitle]`
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
An extension author can now completely modify the label texts of all buttons.
|
||||
|
||||
.. index:: TCA, ext:backend
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-83608-1669634686:
|
||||
|
||||
=======================================================================
|
||||
Feature: #83608 - PSR-14 event to modify resolved default upload folder
|
||||
=======================================================================
|
||||
|
||||
See :issue:`83608`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A new PSR-14 event :php:`\TYPO3\CMS\Core\Resource\Event\AfterDefaultUploadFolderWasResolvedEvent`
|
||||
has been added, which allows the default upload folder to be modified after it has
|
||||
been resolved for the current page or user.
|
||||
|
||||
The new event can be used as a better alternative to the
|
||||
:php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauthgroup.php']['getDefaultUploadFolder']`
|
||||
hook, serving the same purpose.
|
||||
|
||||
The event features the following methods:
|
||||
|
||||
- :php:`getUploadFolder()` returns the currently resolved :php:`$uploadFolder`
|
||||
- :php:`setUploadFolder()` sets a new upload folder
|
||||
- :php:`getPid()` returns the PID of the record we fetch the upload folder for
|
||||
- :php:`getTable()` returns the table name of the record we fetch the upload folder for
|
||||
- :php:`getFieldName()` returns the field name of the record we fetch the upload folder for
|
||||
|
||||
Registration of the event in your extension's :file:`Services.yaml`:
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: EXT:my_extension/Configuration/Services.yaml
|
||||
|
||||
MyVendor\MyExtension\Resource\EventListener\MyEventListener:
|
||||
tags:
|
||||
- name: event.listener
|
||||
identifier: 'my-extension/after-default-upload-folder-was-resolved-event-listener'
|
||||
|
||||
The corresponding event listener class:
|
||||
|
||||
.. code-block:: php
|
||||
:caption: EXT:my_extension/Classes/Resources/EventListener/MyEventListener.php
|
||||
|
||||
namespace MyVendor\MyExtension\Resource\EventListener;
|
||||
|
||||
use TYPO3\CMS\Core\Resource\Event\AfterDefaultUploadFolderWasResolvedEvent;
|
||||
|
||||
final class MyEventListener
|
||||
{
|
||||
public function __invoke(AfterDefaultUploadFolderWasResolvedEvent $event): void
|
||||
{
|
||||
$event->setUploadFolder($event->getUploadFolder()->getStorage()->getFolder('/'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
As resolving the event was moved from :php:`BackendUserAuthentication` to its own
|
||||
:php:`DefaultUploadFolderResolver` class, this event is now the preferred way
|
||||
of modifying the default upload folder.
|
||||
|
||||
.. index:: Backend, PHP-API, ext:core
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-83608-1668162306:
|
||||
|
||||
===========================================================================
|
||||
Feature: #83608 - Page TSconfig setting "options.defaultUploadFolder" added
|
||||
===========================================================================
|
||||
|
||||
See :issue:`83608`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A new page TSconfig option :typoscript:`options.defaultUploadFolder` is added.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Identical to the user TSconfig setting :typoscript:`options.defaultUploadFolder`,
|
||||
this allows default upload folder per page to be set.
|
||||
|
||||
If specified and the given folder exists, this setting will override the value
|
||||
defined in user TSconfig.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
# Set default upload folder to "fileadmin/page_upload" on PID 1
|
||||
[page["uid"] == 1]
|
||||
options.defaultUploadFolder = 1:/page_upload/
|
||||
[end]
|
||||
|
||||
.. index:: TSConfig, ext:core
|
||||
@@ -0,0 +1,68 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-84594-1674211080:
|
||||
|
||||
======================================================
|
||||
Feature: #84594 - Additional parameters to email links
|
||||
======================================================
|
||||
|
||||
See :issue:`84594`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Editors in TYPO3 now have more possibilities to set options when
|
||||
creating a link to a specific email address, in accordance with the "mailto:"
|
||||
protocol.
|
||||
|
||||
This way, editors can now pre-fill the fields "subject", "CC", "BCC"
|
||||
and "body" in the TYPO3 backend when creating a link to an email
|
||||
address, which are then percent-encoded to the actual email link.
|
||||
|
||||
In addition, the `<f:link.email>` ViewHelper has the same additional
|
||||
attributes as well:
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<f:link.email
|
||||
email="foo@bar.tld"
|
||||
subject="Check out this website"
|
||||
cc="foo@example.com"
|
||||
bcc="bar@example.com"
|
||||
>
|
||||
some custom content
|
||||
</f:link.email>
|
||||
|
||||
All of the properties and the link fields are optional.
|
||||
|
||||
For custom email links, it is now also possible to restrict the additional
|
||||
options via TCA:
|
||||
|
||||
Example configuration
|
||||
---------------------
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
'header_link' => [
|
||||
'label' => 'Link',
|
||||
'config' => [
|
||||
'type' => 'link',
|
||||
'allowedTypes' => ['email'],
|
||||
'size' => 50,
|
||||
'appearance' => [
|
||||
// new options are "body", "cc", "bcc" and "subject"
|
||||
'allowedOptions' => ['body', 'cc'],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Editors now have more flexibility when creating links to emails in the
|
||||
TYPO3 backend.
|
||||
|
||||
Integrators have more flexibility when creating links within Fluid
|
||||
templates.
|
||||
|
||||
.. index:: Backend
|
||||
@@ -0,0 +1,29 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-86880-1659742357:
|
||||
|
||||
=======================================================
|
||||
Feature: #86880 - Enable password view at backend login
|
||||
=======================================================
|
||||
|
||||
See :issue:`86880`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
On clicking, the TYPO3 backend login now displays an additional button to reveal the user's
|
||||
password, once something has been typed in the password field.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
A user who is about to log in to the backend is now able to reveal the typed
|
||||
password. Once the password field is cleared, the visibility mode automatically
|
||||
switches back to its default to avoid revealing sensitive data by accident.
|
||||
|
||||
.. warning::
|
||||
Revealing login credentials is always a security risk. Please use this
|
||||
feature with caution when nobody can watch your input, either remotely or by
|
||||
looking over your shoulders!
|
||||
|
||||
.. index:: Backend, ext:backend
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-94499-1675615684:
|
||||
|
||||
================================================================
|
||||
Feature: #94499 - Implement AddPageTypeZeroSource event listener
|
||||
================================================================
|
||||
|
||||
See :issue:`94499`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A new event listener for :ref:`\\TYPO3\\CMS\\Redirects\\Event\\SlugRedirectChangeItemCreatedEvent <feature-99746-1675059434>`
|
||||
is introduced, which creates a :ref:`\\TYPO3\\CMS\\Redirects\\RedirectUpdate\\PageTypeSource <feature-94499-1675615570>` for a page
|
||||
before the slug has been changed. The full URI is built to fill the `source_host`
|
||||
and `source_path`, which takes configured `RouteEnhancers` and `RouteDecorators`
|
||||
into account, for example, the `PageType route decorator`.
|
||||
|
||||
.. note::
|
||||
|
||||
If `source_host` and `source_path` lead to the same outcome for page type 0
|
||||
using full URI building, like the :php:`\TYPO3\CMS\Redirects\RedirectUpdate\PlainSlugReplacementSource`, the
|
||||
:php:`PlainSlugReplacementSource` is replaced with the :php:`PageTypeSource`.
|
||||
|
||||
It is not possible to configure page types for which sources should be added. If
|
||||
you need to do so, read :ref:`additional PageTypeSource auto-create redirect source type <feature-94499-1675615570>`
|
||||
which provides an example of how to implement custom event listeners based on
|
||||
:php:`PageTypeSource`.
|
||||
|
||||
If :php:`PageTypeSource` for page type `0` results in a different
|
||||
source, the :php:`PlainSlugReplacementSource` is not removed to keep the original
|
||||
behaviour, which some instances may rely on.
|
||||
|
||||
This behaviour can be modified by adding an event listener for
|
||||
:ref:`SlugRedirectChangeItemCreatedEvent <feature-99746-1675059434>`
|
||||
|
||||
Remove plain slug source if page type 0 differs:
|
||||
------------------------------------------------
|
||||
|
||||
Registration of the event in your extension's :file:`Services.yaml`:
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: EXT:my_extension/Configuration/Services.yaml
|
||||
|
||||
MyExtension\MyPackage\Redirects\MyEventListener:
|
||||
tags:
|
||||
- name: event.listener
|
||||
identifier: 'my-extension/custom-page-type-redirect'
|
||||
# Registering after core listener is important, otherwise we would
|
||||
# not know if there is a PageType source for page type 0
|
||||
after: 'redirects-add-page-type-zero-source'
|
||||
|
||||
The corresponding event listener class:
|
||||
|
||||
.. code-block:: php
|
||||
:caption: EXT:my_package/Classes/Redirects/MyEventListener.php
|
||||
|
||||
namespace MyVendor\MyExtension\Redirects;
|
||||
|
||||
use TYPO3\CMS\Redirects\Event\SlugRedirectChangeItemCreatedEvent;
|
||||
use TYPO3\CMS\Redirects\RedirectUpdate\PageTypeSource;
|
||||
use TYPO3\CMS\Redirects\RedirectUpdate\PlainSlugReplacementRedirectSource;
|
||||
use TYPO3\CMS\Redirects\RedirectUpdate\RedirectSourceCollection;
|
||||
use TYPO3\CMS\Redirects\RedirectUpdate\RedirectSourceInterface;
|
||||
|
||||
final class MyEventListener
|
||||
{
|
||||
public function __invoke(
|
||||
SlugRedirectChangeItemCreatedEvent $event
|
||||
): void {
|
||||
$changeItem = $event->getSlugRedirectChangeItem();
|
||||
$sources = $changeItem->getSourcesCollection()->all();
|
||||
$pageTypeZeroSource = $this->getPageTypeZeroSource(
|
||||
...array_values($sources)
|
||||
);
|
||||
if ($pageTypeZeroSource === null) {
|
||||
// nothing we can do - no page type 0 source found
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove plain slug replacement redirect source from sources. We
|
||||
// already know, that if it is there it differs from the page type
|
||||
// 0 source, therefor it is safe to simply remove it by class check.
|
||||
$sources = array_filter(
|
||||
$sources,
|
||||
static fn ($source) => !($source instanceof PlainSlugReplacementRedirectSource)
|
||||
);
|
||||
|
||||
// update sources
|
||||
$changeItem = $changeItem->withSourcesCollection(
|
||||
new RedirectSourceCollection(
|
||||
...array_values($sources)
|
||||
)
|
||||
);
|
||||
|
||||
// update change item with updated sources
|
||||
$event->setSlugRedirectChangeItem($changeItem);
|
||||
}
|
||||
|
||||
private function getPageTypeZeroSource(
|
||||
RedirectSourceInterface ...$sources
|
||||
): ?PageTypeSource {
|
||||
foreach ($sources as $source) {
|
||||
if ($source instanceof PageTypeSource
|
||||
&& $source->getPageType() === 0
|
||||
) {
|
||||
return $source;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
An additional redirect source is automatically added if a `PageType suffix`
|
||||
is configured in the :php:`SiteConfiguration` for page type `0`. In that case
|
||||
two redirects are created, one for the plain slug change and one with the suffix
|
||||
in the `source_path`. That way it does not break instances relying on the
|
||||
fact that plain slug based redirects are created.
|
||||
|
||||
.. note::
|
||||
|
||||
This behaviour can be modified by adding an event listener for
|
||||
:ref:`SlugRedirectChangeItemCreatedEvent <feature-99746-1675059434>`.
|
||||
It can check if both variants are in the source collection and remove the
|
||||
:php:`PlainSlugReplacementSource`, as found in the example above.
|
||||
|
||||
.. todo:
|
||||
|
||||
Add link to main documentation or EXT:redirects once this contains more examples for the new events.
|
||||
The documentation will later be modified to include more examples.
|
||||
|
||||
.. index:: PHP-API, ext:redirects
|
||||
+214
@@ -0,0 +1,214 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-94499-1675615570:
|
||||
|
||||
======================================================================================
|
||||
Feature: #94499 - Provide additional `PageTypeSource` auto-create redirect source type
|
||||
======================================================================================
|
||||
|
||||
See :issue:`94499`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A new source type implementation based on :php:`\TYPO3\CMS\Redirects\RedirectUpdate\RedirectSourceInterface`
|
||||
is added, providing the page type number as an additional value. The main use case
|
||||
for this source type is to provide additional source types where the source host
|
||||
and path are taken from a fully built URI before the page slug change occurred for
|
||||
a specific page type. That avoids the need for extension authors to implement a
|
||||
custom source type for the same task, and instead provides a custom event
|
||||
listener to build sources for non-zero page types. Sources can be added by
|
||||
implementing an event listener for
|
||||
:ref:`\\TYPO3\\CMS\\Redirects\\Event\\SlugRedirectChangeItemCreatedEvent <feature-99746-1675059434>`.
|
||||
|
||||
.. note::
|
||||
|
||||
TYPO3 Core implements a listener to add a :php:`PageTypeSource` for page
|
||||
type `0` with :ref:`AddPageTypeZeroSource Event Listener <feature-94499-1675615684>`.
|
||||
This source class can be re-used, if page type related sources should be added
|
||||
for non-zero page types.
|
||||
|
||||
This class features the following methods:
|
||||
|
||||
- :php:`getHost()`: Returns the source host for the redirect
|
||||
- :php:`getPath()`: Returns the source path for the redirect
|
||||
- :php:`getPageType()`: Returns the page type used to provide the host/path
|
||||
- :php:`getTargetLinkParameters()`: Returns the link parameters which should
|
||||
be used to create the target based on `t3://` syntax
|
||||
|
||||
Values can be set only by the constructor.
|
||||
|
||||
Example:
|
||||
--------
|
||||
|
||||
Registration of the event in your extension's :file:`Services.yaml`:
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: EXT:my_extension/Configuration/Services.yaml
|
||||
|
||||
MyVendor\MyExtension\Redirects\MyEventListener:
|
||||
tags:
|
||||
- name: event.listener
|
||||
identifier: 'my-extension/custom-page-type-redirect'
|
||||
after: 'redirects-add-page-type-zero-source'
|
||||
|
||||
The corresponding event listener class:
|
||||
|
||||
.. code-block:: php
|
||||
:caption: EXT:my_extension/Classes/Redirects/MyEventListener.php
|
||||
|
||||
namespace MyVendor\MyExtension\Redirects;
|
||||
|
||||
use TYPO3\CMS\Core\Context\Context;
|
||||
use TYPO3\CMS\Core\Routing\InvalidRouteArgumentsException;
|
||||
use TYPO3\CMS\Core\Routing\RouterInterface;
|
||||
use TYPO3\CMS\Core\Routing\UnableToLinkToPageException;
|
||||
use TYPO3\CMS\Core\Site\Entity\Site;
|
||||
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Redirects\Event\SlugRedirectChangeItemCreatedEvent;
|
||||
use TYPO3\CMS\Redirects\RedirectUpdate\PageTypeSource;
|
||||
use TYPO3\CMS\Redirects\RedirectUpdate\RedirectSourceCollection;
|
||||
use TYPO3\CMS\Redirects\RedirectUpdate\RedirectSourceInterface;
|
||||
|
||||
final class MyEventListener
|
||||
{
|
||||
protected array $customPageTypes = [ 1234, 169999 ];
|
||||
|
||||
public function __invoke(
|
||||
SlugRedirectChangeItemCreatedEvent $event
|
||||
): void {
|
||||
$changeItem = $event->getSlugRedirectChangeItem();
|
||||
$sources = $changeItem->getSourcesCollection()->all();
|
||||
|
||||
foreach ($this->customPageTypes as $pageType) {
|
||||
try {
|
||||
$pageTypeSource = $this->createPageTypeSource(
|
||||
$changeItem->getPageId(),
|
||||
$pageType,
|
||||
$changeItem->getSite(),
|
||||
$changeItem->getSiteLanguage(),
|
||||
);
|
||||
if ($pageTypeSource === null) {
|
||||
continue;
|
||||
}
|
||||
} catch (UnableToLinkToPageException) {
|
||||
// Could not properly link to page. Continue to next page type
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->isDuplicate($pageTypeSource, ...$sources)) {
|
||||
// not adding duplicate,
|
||||
continue;
|
||||
}
|
||||
|
||||
$sources[] = $pageTypeSource;
|
||||
}
|
||||
|
||||
// update sources
|
||||
$changeItem = $changeItem->withSourcesCollection(
|
||||
new RedirectSourceCollection(
|
||||
...array_values($sources)
|
||||
)
|
||||
);
|
||||
|
||||
// update change item with updated sources
|
||||
$event->setSlugRedirectChangeItem($changeItem);
|
||||
}
|
||||
|
||||
private function isDuplicate(
|
||||
PageTypeSource $pageTypeSource,
|
||||
RedirectSourceInterface ...$sources
|
||||
): bool {
|
||||
foreach ($sources as $existingSource) {
|
||||
$existingHost = $existingSource->getHost();
|
||||
$pageTypeSourceHost = $pageTypeSource->getHost();
|
||||
$existingPath = rtrim($existingSource->getPath(), '/');
|
||||
$pageTypeSourcePath = rtrim($pageTypeSource->getPath(), '/');
|
||||
if ($existingSource instanceof PageTypeSource
|
||||
&& $existingHost === $pageTypeSourceHost
|
||||
&& $existingPath === $pageTypeSourcePath
|
||||
) {
|
||||
// we do not check for the type, as that is irrelevant. Same
|
||||
// host+path tuple would lead to duplicated redirects if
|
||||
// type differs.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function createPageTypeSource(
|
||||
int $pageUid,
|
||||
int $pageType,
|
||||
Site $site,
|
||||
SiteLanguage $siteLanguage
|
||||
): ?PageTypeSource {
|
||||
if ($pageType === 0) {
|
||||
// pageType 0 is handled by \TYPO3\CMS\Redirects\EventListener\AddPageTypeZeroSource
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$context = $this->getAdjustedContext();
|
||||
$uri = $site->getRouter($context)->generateUri(
|
||||
$pageUid,
|
||||
[
|
||||
'_language' => $siteLanguage,
|
||||
'type' => $pageType,
|
||||
],
|
||||
'',
|
||||
RouterInterface::ABSOLUTE_URL
|
||||
);
|
||||
return new PageTypeSource(
|
||||
$uri->getHost() ?: '*',
|
||||
$uri->getPath(),
|
||||
$pageType,
|
||||
[
|
||||
'type' => $pageType,
|
||||
],
|
||||
);
|
||||
} catch (\InvalidArgumentException | InvalidRouteArgumentsException $e) {
|
||||
throw new UnableToLinkToPageException(
|
||||
sprintf(
|
||||
'The link to the page with ID "%d" and type "%d" could not be generated: %s',
|
||||
$pageUid,
|
||||
$pageType,
|
||||
$e->getMessage()
|
||||
),
|
||||
1675618235,
|
||||
$e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the adjusted current context with modified visibility settings
|
||||
* to build source url for hidden or scheduled pages.
|
||||
*/
|
||||
private function getAdjustedContext(): Context
|
||||
{
|
||||
$adjustedVisibility = new VisibilityAspect(
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
$originalContext = GeneralUtility::makeInstance(Context::class);
|
||||
$context = clone $originalContext;
|
||||
$context->setAspect('visibility', $adjustedVisibility);
|
||||
return $context;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
The new :php:`PageTypeSource` can be used to provide additional sources, for example,
|
||||
based on custom page types using full URI building, which would take
|
||||
configured PageTypeSuffix decorators into account. For page type `0` (default), the Core
|
||||
implements an event listener which adds the source based on this source class for
|
||||
page type `0` with :ref:`AddPageTypeZeroSource event listener <feature-94499-1675615684>`.
|
||||
|
||||
.. index:: PHP-API, ext:redirects
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-97389-1673972552:
|
||||
|
||||
======================================================================
|
||||
Feature: #97389 - Add password policy validation for TCA type=password
|
||||
======================================================================
|
||||
|
||||
See :issue:`97389`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
It is now possible to assign a password policy to TCA fields of type
|
||||
`password`. For configured fields, the password policy validator will be used
|
||||
in `DataHandler` to ensure that the new password complies with the configured
|
||||
password policy.
|
||||
|
||||
Password policy requirements are shown below the password field when the focus
|
||||
is changed to the password field.
|
||||
|
||||
The TCA field `password` for tables :sql:`be_users` and :sql:`fe_users` uses
|
||||
now by default the password policy configured in
|
||||
:php:`$GLOBALS['TYPO3_CONF_VARS']['FE']['passwordPolicy']` (fe_users) or
|
||||
:php:`$GLOBALS['TYPO3_CONF_VARS']['BE']['passwordPolicy']` (be_users).
|
||||
|
||||
Example configuration
|
||||
---------------------
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
'password_field' => [
|
||||
'label' => 'Password',
|
||||
'config' => [
|
||||
'type' => 'password',
|
||||
'passwordPolicy' => 'default',
|
||||
],
|
||||
],
|
||||
|
||||
This example will use the password policy `default` for the field.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
For TYPO3 frontend and backend users, the global password policy is used. A
|
||||
new password is not saved if it does not comply with the password policy.
|
||||
|
||||
.. index:: Backend, ext:core
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-97390-1667653394:
|
||||
|
||||
=======================================================================
|
||||
Feature: #97390 - Use password policy for password reset in ext:felogin
|
||||
=======================================================================
|
||||
|
||||
See :issue:`97390`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The password reset feature for TYPO3 frontend users now takes into account the
|
||||
configurable password policy introduced in :ref:`#97388 <feature-97388>`,
|
||||
if the feature toggle `security.usePasswordPolicyForFrontendUsers` is
|
||||
set to `true` (default for new TYPO3 websites).
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Password validation configured through
|
||||
:typoscript:`plugin.tx_felogin_login.settings.passwordValidators` has been
|
||||
marked as deprecated, but will still be used for password validation, if
|
||||
the feature toggle `security.usePasswordPolicyForFrontendUsers` is set
|
||||
to `false`.
|
||||
|
||||
TYPO3 websites, which have the feature toggle
|
||||
`security.usePasswordPolicyForFrontendUsers` set to `true`, will use the globally
|
||||
configured password policy when a TYPO3 frontend user resets their password.
|
||||
The TYPO3 default password policy contains the following password requirements:
|
||||
|
||||
* At least 8 chars
|
||||
* At least one number
|
||||
* At least one upper case char
|
||||
* At least one special char
|
||||
* Must be different than current password (if available)
|
||||
|
||||
.. index:: Frontend, ext:felogin
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-97667-1678967840:
|
||||
|
||||
======================================================
|
||||
Feature: #97667 - Add keyboard support for Multiselect
|
||||
======================================================
|
||||
|
||||
See :issue:`97667`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
You are able to use the keyboard for selecting and deselecting options in
|
||||
Multiselect.
|
||||
|
||||
- :kbd:`Enter` adds options, either from right to left or left to right
|
||||
- :kbd:`Delete` or :kbd:`Backspace` removes an option for windows/mac users
|
||||
- :kbd:`Alt` + :kbd:`ArrowUp` moves the option one up
|
||||
- :kbd:`Alt` + :kbd:`ArrowDown` moves the option one down
|
||||
- :kbd:`Alt` + :kbd:`Shift` + :kbd:`ArrowUp` moves it to the top
|
||||
- :kbd:`Alt` + :kbd:`Shift` + :kbd:`ArrowDown` moves it to the bottom
|
||||
|
||||
More combinations are possible by default:
|
||||
|
||||
- :kbd:`Shift` + :kbd:`ArrowUp` includes the upper option
|
||||
- :kbd:`Shift` + :kbd:`ArrowDown` includes the lower option
|
||||
- :kbd:`Home` moves the cursor to the top
|
||||
- :kbd:`End` move the cursor to the bottom
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
This currently affects the following TCA configurations:
|
||||
|
||||
- :php:`'type' => 'select', 'renderType' => 'selectMultipleSideBySide'`
|
||||
- :php:`'type' => 'group'`
|
||||
- :php:`'type' => 'folder'`
|
||||
|
||||
.. index:: TCA, ext:backend
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-98132-1677928250:
|
||||
|
||||
===============================================================
|
||||
Feature: #98132 - Extbase entity properties support union types
|
||||
===============================================================
|
||||
|
||||
See :issue:`98132`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Extbase reflection now supports the detection of union types in entity properties.
|
||||
|
||||
Previously, whenever a union type was needed, union type declarations led to Extbase
|
||||
not detecting any type at all, resulting in the property not being mapped. Union
|
||||
types could be resolved via doc blocks however:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
class Entity extends AbstractEntity
|
||||
{
|
||||
/**
|
||||
* @var ChildEntity|LazyLoadingProxy
|
||||
*/
|
||||
private $property;
|
||||
}
|
||||
|
||||
Now this is possible:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
class Entity extends AbstractEntity
|
||||
{
|
||||
private ChildEntity|LazyLoadingProxy $property;
|
||||
}
|
||||
|
||||
This is especially useful for lazy loaded relations where the property type is `LazyLoadingProxy|ChildEntity`.
|
||||
|
||||
There is something important to understand about how Extbase detects unions when
|
||||
it comes to property mapping, i.e. when a database row is mapped onto an object.
|
||||
In this case, Extbase needs to know the desired target type - no union, no
|
||||
intersection, just one type. In order to achieve this, Extbase uses the first
|
||||
declared type as a so-called primary type.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
class Entity extends AbstractEntity
|
||||
{
|
||||
private string|int $property;
|
||||
}
|
||||
|
||||
In this case, `string` is the primary type. `int|string` would result in `int` as primary type.
|
||||
|
||||
There is one important thing to note and one exception to this rule. First of
|
||||
all, `null` is not considered a type. `null|string` results in primary type
|
||||
`string`, which is nullable. `null|string|int` also results in primary type
|
||||
`string`. In fact, `null` means that all other types are nullable.
|
||||
`null|string|int` boils down to `?string` or `?int`.
|
||||
|
||||
Secondly, `LazyLoadingProxy` is never detected as primary type because it is
|
||||
just a proxy and not the actual target type, once loaded.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
class Entity extends AbstractEntity
|
||||
{
|
||||
private LazyLoadingProxy|ChildEntity $property;
|
||||
}
|
||||
|
||||
Extbase supports this and detects `ChildEntity` as primary type, although
|
||||
`LazyLoadingProxy` is the first item in the list. However, it is recommended to
|
||||
place the actual type first, for consistency reasons: `ChildEntity|LazyLoadingProxy`.
|
||||
|
||||
A final word on `LazyObjectStorage`: `LazyObjectStorage` is a subclass of
|
||||
`ObjectStorage`, therefore the following code works and has always worked:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
class Entity extends AbstractEntity
|
||||
{
|
||||
/**
|
||||
* @var ObjectStorage<ChildEntity>
|
||||
* @TYPO3\CMS\Extbase\Annotation\ORM\Lazy
|
||||
*/
|
||||
private ObjectStorage $property;
|
||||
}
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
As described above, the main impact is Extbase being able to detect and support
|
||||
union type declarations for entity properties.
|
||||
|
||||
.. index:: PHP-API, ext:extbase
|
||||
@@ -0,0 +1,40 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-98517-1675861888:
|
||||
|
||||
=========================================================
|
||||
Feature: #98517 - Username in backend password reset mail
|
||||
=========================================================
|
||||
|
||||
See :issue:`98517`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Many users forget their login username and try to login with their email address.
|
||||
The username of the backend user is now displayed in the password recovery email
|
||||
alongside the reset link.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
The username of the backend user is displayed in the password recovery email
|
||||
alongside the reset link.
|
||||
|
||||
.. note::
|
||||
|
||||
Be aware, this feature comes with security risks:
|
||||
|
||||
Previously, a third-party that gained access to the email account could only
|
||||
reset the password of the TYPO3 backend user, but not login if the username
|
||||
was different to the email address.
|
||||
|
||||
Now it has all the information needed to login into the TYPO3 backend and
|
||||
potentially could cause damage to the website.
|
||||
|
||||
We highly recommend protecting backend accounts using :doc:`MFA <../11.1/Feature-93526-MultiFactorAuthentication>`.
|
||||
|
||||
It is also possible to override the ResetPassword email template to remove
|
||||
the username and customize the result.
|
||||
|
||||
.. index:: LocalConfiguration, ext:backend
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-99258-1670017157:
|
||||
|
||||
=======================================================================================
|
||||
Feature: #99258 - Add minimum age option to EXT:lowlevel cleanup:deletedrecords command
|
||||
=======================================================================================
|
||||
|
||||
See :issue:`99258`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Using the CLI command `cleanup:deletedrecords` to clean up the database
|
||||
periodically is not really possible with EXT:recycler, because all
|
||||
records marked for deletion are deleted immediately and thus the recycler seems
|
||||
less useful.
|
||||
|
||||
The new option `--min-age` added to the `cleanup:deletedrecords` CLI command
|
||||
allows a minimum age of the X days that a record needs to be marked as deleted
|
||||
before it really gets deleted to be defined.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Executing `bin/typo3 cleanup:deletedrecords --min-age 30` will only delete
|
||||
records that have been marked for more than 30 days for deletion.
|
||||
|
||||
.. index:: CLI, ext:lowlevel
|
||||
@@ -0,0 +1,31 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-99321-1670525282:
|
||||
|
||||
================================================
|
||||
Feature: #99321 - Add presets for site languages
|
||||
================================================
|
||||
|
||||
See :issue:`99321`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
When adding a new language to a site, an integrator can now
|
||||
choose
|
||||
|
||||
a) to create a new language by defining all values themselves
|
||||
b) from a list of default language settings ("presets")
|
||||
c) to use an existing language if it is already used in a different site
|
||||
|
||||
Although c) is always recommended when working with multi-site setups,
|
||||
to keep language IDs between sites in sync, b) is now a quick start
|
||||
to setup a new site.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Integrators spend less time adding new site languages.
|
||||
|
||||
|
||||
.. index:: Backend, ext:core
|
||||
@@ -0,0 +1,28 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-99436-1672410981:
|
||||
|
||||
===================================================
|
||||
Feature: #99436 - List commands in scheduler module
|
||||
===================================================
|
||||
|
||||
See :issue:`99436`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Commands based on Symfony commands are the successor of regular tasks since TYPO3 v8.
|
||||
|
||||
The scheduler submodule :guilabel:`Available scheduler commands & tasks` has been extended
|
||||
to list not only available scheduler tasks, but CLI commands that can be added
|
||||
as scheduler tasks.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
The submodule :guilabel:`Available scheduler commands & tasks` has been improved to
|
||||
list schedulable commands as well. This improves the overview and makes it easier
|
||||
to set up commands.
|
||||
|
||||
.. index:: Backend, ext:scheduler
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-99499-1677703100:
|
||||
|
||||
============================================================
|
||||
Feature: #99499 - Introduce Content-Security-Policy handling
|
||||
============================================================
|
||||
|
||||
See :issue:`99499`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A corresponding representation of the W3C standard of
|
||||
`Content-Security-Policy (CSP) <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy>`__
|
||||
has been introduced to TYPO3. Content-Security-Policy declarations can either be provided by using
|
||||
the general builder pattern of :php:`\TYPO3\CMS\Core\Security\ContentSecurityPolicy\Policy`, extension-specific
|
||||
mutations (changes to the general policy) via :file:`Configuration/ContentSecurityPolicies.php`
|
||||
located in corresponding extension directories, or YAML path :yaml:`contentSecurityPolicies.mutations` for
|
||||
site-specific declarations in the website frontend.
|
||||
|
||||
The PSR-15 middlewares :php:`ContentSecurityPolicyHeaders` apply `Content-Security-Policy` HTTP headers
|
||||
to each response in the frontend and backend scope. In the case that other components have already added either the
|
||||
header `Content-Security-Policy` or `Content-Security-Policy-Report-Only`, those existing headers will be
|
||||
kept without any modification - these events will be logged with an `info` severity.
|
||||
|
||||
To delegate CSP handling to TYPO3, the scope-specific feature flags need to be enabled:
|
||||
|
||||
* :php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['security.backend.enforceContentSecurityPolicy']`
|
||||
* :php:`$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['security.frontend.enforceContentSecurityPolicy']`
|
||||
|
||||
For new installations `security.backend.enforceContentSecurityPolicy` is enabled via factory default settings.
|
||||
|
||||
Potential CSP violations are reported back to the TYPO3 system and persisted internally in the database table
|
||||
:sql:`sys_http_report`. A corresponding Content-Security-Policy backend module supports users to keep track of
|
||||
recent violations and - if applicable - to select potential resolutions (stored in database table
|
||||
:sql:`sys_csp_resolution`) which extends the Content-Security-Policy for the given scope during runtime.
|
||||
|
||||
As an alternative, the reporting URL can be configured to use third-party services as well:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS']['BE']['contentSecurityPolicyReportingUrl']
|
||||
= 'https://csp-violation.example.org/';
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['contentSecurityPolicyReportingUrl']
|
||||
= 'https://csp-violation.example.org/';
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Introducing CSP to TYPO3 aims to reduce the risk of being affected by Cross-Site-Scripting
|
||||
due to the lack of proper encoding of user-submitted content in corresponding outputs.
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
`Policy` builder approach
|
||||
-------------------------
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\Directive;
|
||||
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\Policy;
|
||||
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\SourceKeyword;
|
||||
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\SourceScheme;
|
||||
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue;
|
||||
use TYPO3\CMS\Core\Security\Nonce;
|
||||
|
||||
$nonce = Nonce::create();
|
||||
$policy = (new Policy())
|
||||
// results in `default-src 'self'`
|
||||
->default(SourceKeyword::self)
|
||||
// extends the ancestor directive ('default-src'), thus reuses 'self' and adds additional sources
|
||||
// results in `img-src 'self' data: https://*.typo3.org`
|
||||
->extend(Directive::ImgSrc, SourceScheme::data, new UriValue('https://*.typo3.org'))
|
||||
// extends the ancestor directive ('default-src'), thus reuses 'self' and adds additional sources
|
||||
// results in `script-src 'self' 'nonce-[random]'` ('nonce-proxy' is substituted when compiling the policy)
|
||||
->extend(Directive::ScriptSrc, SourceKeyword::nonceProxy)
|
||||
// sets (overrides) the directive, thus ignores 'self' of the 'default-src' directive
|
||||
// results in `worker-src blob:`
|
||||
->set(Directive::WorkerSrc, SourceScheme::blob);
|
||||
header('Content-Security-Policy: ' . $policy->compile($nonce));
|
||||
|
||||
The result of the compiled and serialized result as HTTP header would look similar to this
|
||||
(the following sections are using the same example, but utilize different techniques for the declarations).
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
Content-Security-Policy: default-src 'self';
|
||||
img-src 'self' data: https://*.typo3.org; script-src 'self' 'nonce-[random]';
|
||||
worker-src blob:
|
||||
|
||||
Extension-specific
|
||||
------------------
|
||||
|
||||
A file :file:`Configuration/ContentSecurityPolicies.php` in the base directory
|
||||
of any extension will automatically provide and apply corresponding settings.
|
||||
|
||||
.. code-block:: php
|
||||
:caption: EXT:my_extension/Configuration/ContentSecurityPolicies.php
|
||||
|
||||
<?php
|
||||
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\Directive;
|
||||
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\Mutation;
|
||||
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\MutationCollection;
|
||||
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\MutationMode;
|
||||
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\Scope;
|
||||
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\SourceKeyword;
|
||||
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\SourceScheme;
|
||||
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue;
|
||||
use TYPO3\CMS\Core\Type\Map;
|
||||
|
||||
return Map::fromEntries([
|
||||
// provide declarations for the backend
|
||||
Scope::backend(),
|
||||
|
||||
// NOTICE: When using `MutationMode::Set` existing declarations will be overridden
|
||||
new MutationCollection(
|
||||
// results in `default-src 'self'`
|
||||
new Mutation(MutationMode::Set, Directive::DefaultSrc, SourceKeyword::self),
|
||||
|
||||
// extends the ancestor directive ('default-src'), thus reuses 'self' and adds additional sources
|
||||
// results in `img-src 'self' data: https://*.typo3.org`
|
||||
new Mutation(MutationMode::Extend, Directive::ImgSrc, SourceScheme::data, new UriValue('https://*.typo3.org')),
|
||||
// NOTICE: the following two instructions for `Directive::ImgSrc` are identical to the previous instruction,
|
||||
// `MutationMode::Extend` is a shortcut for `MutationMode::InheritOnce` and `MutationMode::Append`
|
||||
// new Mutation(MutationMode::InheritOnce, Directive::ImgSrc, SourceScheme::data),
|
||||
// new Mutation(MutationMode::Append, Directive::ImgSrc, SourceScheme::data, new UriValue('https://*.typo3.org')),
|
||||
|
||||
// extends the ancestor directive ('default-src'), thus reuses 'self' and adds additional sources
|
||||
// results in `script-src 'self' 'nonce-[random]'` ('nonce-proxy' is substituted when compiling the policy)
|
||||
new Mutation(MutationMode::Extend, Directive::ScriptSrc, SourceKeyword::nonceProxy),
|
||||
|
||||
// sets (overrides) the directive, thus ignores 'self' of the 'default-src' directive
|
||||
// results in `worker-src blob:`
|
||||
new Mutation(MutationMode::Set, Directive::WorkerSrc, SourceScheme::blob),
|
||||
),
|
||||
]);
|
||||
|
||||
Site-specific (frontend)
|
||||
------------------------
|
||||
|
||||
In the frontend, the dedicated :file:`sites/<my-site>/csp.yaml` can be used to declare CSP for a specific site as well.
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: config/sites/<my-site>/csp.yaml
|
||||
|
||||
# inherits default site-unspecific frontend policy mutations (enabled per default)
|
||||
inheritDefault: true
|
||||
mutations:
|
||||
# results in `default-src 'self'`
|
||||
- mode: set
|
||||
directive: 'default-src'
|
||||
sources:
|
||||
- "'self'"
|
||||
# extends the ancestor directive ('default-src'), thus reuses 'self' and adds additional sources
|
||||
# results in `img-src 'self' data: https://*.typo3.org`
|
||||
- mode: extend
|
||||
directive: 'img-src'
|
||||
sources:
|
||||
- 'data:'
|
||||
- 'https://*.typo3.org'
|
||||
# extends the ancestor directive ('default-src'), thus reuses 'self' and adds additional sources
|
||||
# results in `script-src 'self' 'nonce-[random]'` ('nonce-proxy' is substituted when compiling the policy)
|
||||
- mode: extend
|
||||
directive: 'script-src'
|
||||
sources:
|
||||
- "'nonce-proxy'"
|
||||
# results in `worker-src blob:`
|
||||
- mode: set
|
||||
directive: 'worker-src'
|
||||
sources:
|
||||
- 'blob:'
|
||||
|
||||
PSR-14 events
|
||||
=============
|
||||
|
||||
PolicyMutatedEvent
|
||||
------------------
|
||||
|
||||
The :php:`\TYPO3\CMS\Core\Security\ContentSecurityPolicy\Event\PolicyMutatedEvent` will
|
||||
be dispatched once all mutations have been applied to the current policy object, just
|
||||
before the corresponding HTTP header is added to the HTTP response object.
|
||||
This allows individual changes for custom implementations. Next to the :php:`Scope`, the
|
||||
:php:`Policy`'s and the :php:`MutationCollection`'s might the Event also provide
|
||||
the current PSR-7 :php:`ServerRequestInterface` for additional context.
|
||||
|
||||
InvestigateMutationsEvent
|
||||
-------------------------
|
||||
|
||||
The :php:`\TYPO3\CMS\Core\Security\ContentSecurityPolicy\Event\InvestigateMutationsEvent` will
|
||||
be dispatched when the Content-Security-Policy backend module searches for potential resolutions
|
||||
to a specific CSP violation report. This way, third-party integrations that rely on external resources
|
||||
(for example, maps, file storage, content processing/translation, ...) can provide the necessary mutations.
|
||||
|
||||
.. index:: Backend, Fluid, Frontend, LocalConfiguration, PHP-API, ext:core
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-99608-1674053552:
|
||||
|
||||
=============================================================================
|
||||
Feature: #99608 - Add password policy action to exclude validators in SU mode
|
||||
=============================================================================
|
||||
|
||||
See :issue:`99608`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The new password policy action `UPDATE_USER_PASSWORD_SWITCH_USER_MODE` has been
|
||||
added in order to allow administrators to exclude a password policy validator,
|
||||
if the current user is in switch user mode.
|
||||
|
||||
The new password policy action is used in the global default password policy for
|
||||
the `NotCurrentPasswordValidator`.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
When the current backend user is in switch user mode, it is not validated,
|
||||
if the new password equals the current user password in ext:setup.
|
||||
|
||||
.. index:: Backend, ext:core
|
||||
@@ -0,0 +1,232 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-99629-1674550092:
|
||||
|
||||
========================================================
|
||||
Feature: #99629 - Webhooks - Outgoing webhooks for TYPO3
|
||||
========================================================
|
||||
|
||||
See :issue:`99629`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A webhook is an automated message sent from one application to another via HTTP.
|
||||
|
||||
This feature adds the possibility to configure webhooks in TYPO3.
|
||||
|
||||
A new backend module :guilabel:`System > Webhooks` provides the possibility to
|
||||
configure webhooks. The module is available in the TYPO3 backend for users with
|
||||
administrative rights.
|
||||
|
||||
A webhook is defined as an authorized POST or GET request to a defined URL.
|
||||
For example, a webhook can be used to send a notification to a Slack channel
|
||||
when a new page is created in TYPO3.
|
||||
|
||||
Any webhook record is defined by a universally unique identifier (UUID), a speaking name, an optional
|
||||
description, a trigger, the target URL and a signing-secret.
|
||||
Both the unique identifier and the signing-secret are generated in the backend
|
||||
when a new webhook is created.
|
||||
|
||||
Triggers provided by the TYPO3 Core
|
||||
-----------------------------------
|
||||
|
||||
The TYPO3 Core currently provides the following triggers for webhooks:
|
||||
|
||||
* Page Modification: Triggers when a page is created, updated or deleted
|
||||
* File Added: Triggers when a file is added
|
||||
* File Updated: Triggers when a file is updated
|
||||
* File Removed: Triggers when a file is removed
|
||||
* Login Error Occurred: Triggers when a login error occurred
|
||||
* Redirect Was Hit: Triggers when a redirect has been hit
|
||||
|
||||
These triggers are meant as a first set of triggers that can be used to send webhooks,
|
||||
further triggers will be added in the future. In most projects however, it is likely
|
||||
that custom triggers are required.
|
||||
|
||||
Custom triggers
|
||||
---------------
|
||||
|
||||
Trigger by PSR-14 events
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Custom triggers can be added by creating a `Message` for an specific PSR-14 event and
|
||||
tagging that message as a webhook message.
|
||||
|
||||
The following example shows how to create a simple webhook message for the
|
||||
:php:`\TYPO3\CMS\Core\Resource\Event\AfterFolderAddedEvent`:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
namespace TYPO3\CMS\Webhooks\Message;
|
||||
|
||||
use TYPO3\CMS\Core\Attribute\WebhookMessage;
|
||||
use TYPO3\CMS\Core\Messaging\WebhookMessageInterface;
|
||||
use TYPO3\CMS\Core\Resource\Event\AfterFolderAddedEvent;
|
||||
|
||||
#[WebhookMessage(
|
||||
identifier: 'typo3/folder-added',
|
||||
description: 'LLL:EXT:webhooks/Resources/Private/Language/locallang_db.xlf:sys_webhook.webhook_type.typo3-folder-added'
|
||||
)]
|
||||
final class FolderAddedMessage implements WebhookMessageInterface
|
||||
{
|
||||
public function __construct(
|
||||
private readonly int $storageUid,
|
||||
private readonly string $identifier,
|
||||
private readonly string $publicUrl
|
||||
) {
|
||||
}
|
||||
|
||||
public static function createFromEvent(AfterFolderAddedEvent $event): self
|
||||
{
|
||||
$file = $event->getFile();
|
||||
return new self($file->getStorage()->getUid(), $file->getIdentifier(), $file->getPublicUrl());
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'storage' => $this->storageUid,
|
||||
'identifier' => $this->identifier,
|
||||
'url' => $this->publicUrl,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
#. Create a final class implementing `\TYPO3\CMS\Core\Messaging\WebhookMessageInterface`.
|
||||
#. Add the :php:`\TYPO3\CMS\Core\Attribute\WebhookMessage` attribute to the class.
|
||||
The attribute requires the following information:
|
||||
|
||||
* `identifier`: The identifier of the webhook message.
|
||||
* `description`: The description of the webhook message. This description
|
||||
is used to describe the trigger in the TYPO3 backend.
|
||||
|
||||
#. Add a static method `createFromEvent()` that creates a new instance of the
|
||||
message from the event you want to use as a trigger.
|
||||
#. Add a method `jsonSerialize()` that returns an array with the data that
|
||||
should be sent with the webhook.
|
||||
|
||||
Trigger by hooks or custom code
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In case a trigger is not provided by the TYPO3 Core or a PSR-14 event is not available,
|
||||
it is possible to create a custom trigger - for example by using a TYPO3 hook.
|
||||
|
||||
The message itself should look similar to the example above, but does not need the
|
||||
:php:`createFromEvent()` method.
|
||||
|
||||
Instead, the custom code (hook implementation) will create the message
|
||||
and dispatch it.
|
||||
|
||||
Example hook implementation for a DataHandler hook (see :php:`\TYPO3\CMS\Webhooks\Listener\PageModificationListener`):
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
public function __construct(
|
||||
protected readonly \Symfony\Component\Messenger\MessageBusInterface $bus
|
||||
) {
|
||||
}
|
||||
|
||||
public function processDatamap_afterDatabaseOperations($status, $table, $id, $fieldArray, DataHandler $dataHandler)
|
||||
{
|
||||
if ($table !== 'pages') {
|
||||
return;
|
||||
}
|
||||
// ...
|
||||
$message = new PageModificationMessage(
|
||||
'new',
|
||||
$id,
|
||||
$fieldArray,
|
||||
$site->getIdentifier(),
|
||||
(string)$site->getRouter()->generateUri($id),
|
||||
$dataHandler->BE_USER,
|
||||
);
|
||||
// ...
|
||||
$this->bus->dispatch($message);
|
||||
}
|
||||
|
||||
Use :file:`Services.yaml` instead of the PHP attribute
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Instead of the PHP attribute the :file:`Services.yaml` can be used to define the
|
||||
webhook message. The following example shows how to define the webhook message
|
||||
from the example above in the :file:`Services.yaml`:
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: EXT:my_extension/Configuration/Services.yaml
|
||||
|
||||
TYPO3\CMS\Webhooks\Message\FolderAddedMessage:
|
||||
tags:
|
||||
- name: 'core.webhook_message'
|
||||
identifier: 'typo3/folder-added'
|
||||
description: 'LLL:EXT:webhooks/Resources/Private/Language/locallang_db.xlf:sys_webhook.webhook_type.typo3-folder-added'
|
||||
|
||||
|
||||
HTTP headers of every webhook
|
||||
-----------------------------
|
||||
|
||||
With every webhook request, the following HTTP headers are sent:
|
||||
|
||||
* Content-Type: application/json
|
||||
* Webhook-Signature-Algo: sha256
|
||||
* Webhook-Signature: <hash>
|
||||
|
||||
The hash is calculated with the secret of the webhook and the JSON encoded data
|
||||
of the request. The hash is created with the PHP function :php:`hash_hmac`.
|
||||
See the following section about the hash calculation.
|
||||
|
||||
Hash calculation
|
||||
----------------
|
||||
|
||||
The hash is calculated with the following PHP code:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$hash = hash_hmac('sha256', sprintf(
|
||||
'%s:%s',
|
||||
$identifier, // The identifier of the webhook (uuid)
|
||||
$body // The JSON encoded body of the request
|
||||
), $secret); // The secret of the webhook
|
||||
|
||||
The hash is sent as HTTP header `Webhook-Signature` and should be used to
|
||||
validate that the request was sent from the TYPO3 instance and has not been
|
||||
manipulated.
|
||||
To verify this on the receiving end, build the hash with the same algorithm and
|
||||
secret and compare it with the hash that was sent with the request.
|
||||
|
||||
The hash is not meant to be used as a security mechanism, but as a way to verify
|
||||
that the request was sent from the TYPO3 instance.
|
||||
|
||||
Technical background and advanced usage
|
||||
---------------------------------------
|
||||
|
||||
The webhook system is based on the Symfony Messenger component. The messages
|
||||
are simple PHP objects that implement an interface that denotes
|
||||
them as webhook messages.
|
||||
|
||||
That message is then dispatched to the Symfony Messenger bus. The TYPO3 Core
|
||||
provides a :php:`\TYPO3\CMS\Webhooks\MessageHandler\WebhookMessageHandler`
|
||||
that is responsible for sending the webhook
|
||||
requests to the third-party system, if configured to do so. The handler looks up
|
||||
the webhook configuration and sends the request to the configured URL.
|
||||
|
||||
Messages are sent to the bus in any case. The handler is then responsible for checking
|
||||
whether or not an external request (webhook) should be sent.
|
||||
|
||||
If advanced request handling is necessary or a custom implementation should be used,
|
||||
a custom handler can be created that handles :php:`WebhookMessageInterface`
|
||||
messages.
|
||||
|
||||
.. seealso::
|
||||
:ref:`More information on messages and their handlers <t3coreapi:message-bus>`
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
The TYPO3 Core now provides a convenient GUI to create and send webhooks to
|
||||
third-party systems.
|
||||
In combination with the system extension :doc:`reactions <ext_reactions:Index>`
|
||||
TYPO3 can now be used as a
|
||||
low-code/no-code integration platform between multiple systems.
|
||||
|
||||
.. index:: Backend, Frontend, PHP-API, ext:webhooks
|
||||
@@ -0,0 +1,38 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-99735-1678701694:
|
||||
|
||||
=================================================
|
||||
Feature: #99735 - New Country Select form element
|
||||
=================================================
|
||||
|
||||
See :issue:`99735`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Since :ref:`feature-99618-1674063182`, TYPO3 provides a list of countries, together with an API
|
||||
and a Fluid form ViewHelper. A new "Country select" form element has now been
|
||||
added to the TYPO3 Form Framework for creating a country select in a form
|
||||
easily. The new form element features a couple of configuration options, which
|
||||
can either be configured via the :guilabel:`Forms` module or directly in the
|
||||
corresponding YAML file.
|
||||
|
||||
Available options
|
||||
-----------------
|
||||
|
||||
- `First option` (:yaml:`prependOptionLabel`): Define the "empty option", i.e. the first element of the select. You can use this to provide additional guidance for the user.
|
||||
- `Prioritized countries` (:yaml:`prioritizedCountries`): Define a list of countries which should be listed as first options in the form element.
|
||||
- `Only countries` (:yaml:`onlyCountries`): Restrict the countries to be rendered in the list.
|
||||
- `Exclude countries` (:yaml:`excludeCountries`): Define which countries should not be shown in the list.
|
||||
|
||||
The new element will be rendered as single select (:html:`<select>`) HTML
|
||||
element in the frontend.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
The new "Country select" form element is now available in the Form
|
||||
Framework with a couple of specific configuration options.
|
||||
|
||||
.. index:: ext:form
|
||||
@@ -0,0 +1,101 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-99739-1674867455:
|
||||
|
||||
======================================================
|
||||
Feature: #99739 - Associative array keys for TCA items
|
||||
======================================================
|
||||
|
||||
See :issue:`99739`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
It is now possible to define associative array keys for the :php:`items`
|
||||
configuration of TCA types :php:`select`, :php:`radio` and :php:`check`. The
|
||||
new keys are called: :php:`label`, :php:`value`, :php:`icon`, :php:`group` and
|
||||
:php:`description`.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
'columns' => [
|
||||
'select' => [
|
||||
'label' => 'My select field',
|
||||
'config' => [
|
||||
'type' => 'select',
|
||||
'renderType' => 'selectSingle',
|
||||
'items' => [
|
||||
[
|
||||
'label' => 'Selection 1',
|
||||
'value' => '1',
|
||||
'icon' => 'my-icon-identifier',
|
||||
'group' => 'default',
|
||||
],
|
||||
[
|
||||
'label' => 'Selection 2',
|
||||
'value' => '2',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'select_checkbox' => [
|
||||
'label' => 'My select checkbox field',
|
||||
'config' => [
|
||||
'type' => 'select',
|
||||
'renderType' => 'selectCheckBox',
|
||||
'items' => [
|
||||
[
|
||||
'label' => 'My select checkbox field',
|
||||
'value' => '1',
|
||||
'icon' => 'my-icon-identifier',
|
||||
'group' => 'default',
|
||||
'description' => 'My custom description',
|
||||
],
|
||||
[
|
||||
'label' => 'My select checkbox field',
|
||||
'value' => '2',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'radio' => [
|
||||
'label' => 'My radio field',
|
||||
'config' => [
|
||||
'type' => 'radio',
|
||||
'items' => [
|
||||
[
|
||||
'label' => 'Radio 1',
|
||||
'value' => '1',
|
||||
],
|
||||
[
|
||||
'label' => 'Radio 2',
|
||||
'value' => '2',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'check' => [
|
||||
'config' => [
|
||||
'type' => 'check',
|
||||
'items' => [
|
||||
[
|
||||
'invertStateDisplay' => true,
|
||||
'label' => 'Click on me',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
It is now much easier and clearer to define the TCA :php:`items` configuration
|
||||
with associative array keys. The struggle to remember which option is first,
|
||||
label or value, is now over. In addition, optional keys like :php:`icon` and
|
||||
:php:`group` can be omitted, for example, when one desires to set the
|
||||
:php:`description` option.
|
||||
|
||||
.. index:: TCA, ext:backend
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-99802-1675370033:
|
||||
|
||||
============================================================================
|
||||
Feature: #99802 - New PSR-14 ModifyRedirectManagementControllerViewDataEvent
|
||||
============================================================================
|
||||
|
||||
See :issue:`99802`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A new PSR-14 event :php:`\TYPO3\CMS\Redirects\Event\ModifyRedirectManagementControllerViewDataEvent`
|
||||
is introduced, allowing extension authors to modify or enrich view data for the
|
||||
:php:`\TYPO3\CMS\Redirects\Controller\ManagementController`. This allows to
|
||||
display more or other information along the way.
|
||||
|
||||
This event features the following methods:
|
||||
|
||||
- :php:`getDemand()`: Return the demand object used to retrieve the redirects
|
||||
- :php:`getRedirects()`: Return the retrieved redirects
|
||||
- :php:`setRedirects()`: Can be used to set the redirects, for example, after enriching redirect fields
|
||||
- :php:`getRequest()`: Return the current request
|
||||
- :php:`getHosts()`: Returns the hosts to be used for the host filter select-box
|
||||
- :php:`setHosts()`: Can be used to update which hosts are available in the filter select-box
|
||||
- :php:`getStatusCodes()`: Returns the status codes for the filter select box
|
||||
- :php:`setStatusCodes()`: Can be used to update which status codes are available in the filter select-box
|
||||
- :php:`getCreationTypes()`: Returns creation types for the filter select box
|
||||
- :php:`setCreationTypes()`: Can be used to update which creation types are available in the filter select-box
|
||||
- :php:`getShowHitCounter()`: Returns if hit counter should be displayed
|
||||
- :php:`setShowHitCounter()`: Can be used to manage if the hit counter should be displayed
|
||||
- :php:`getView()`: Returns the current view object, without controller data assigned yet
|
||||
- :php:`setView()`: Can be used to assign additional data to the view
|
||||
|
||||
For example, this event can be used to add additional information to current page records.
|
||||
|
||||
Therefore, it can be used to generate custom data, directly assigning to the view.
|
||||
With overriding the backend view template via page TSconfig this custom data can
|
||||
be displayed where it is needed, and rendered the way it is wanted.
|
||||
|
||||
|
||||
Example:
|
||||
--------
|
||||
|
||||
Registration of the event listener:
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: EXT:my_extension/Configuration/Services.yaml
|
||||
|
||||
MyVendor\MyExtension\Redirects\MyEventListener:
|
||||
tags:
|
||||
- name: event.listener
|
||||
identifier: 'my-extension/modify-redirect-management-controller-view-data'
|
||||
|
||||
The corresponding event listener class:
|
||||
|
||||
.. code-block:: php
|
||||
:caption: EXT:my_extension/Classes/Redirects/MyEventListener.php
|
||||
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MyVendor\MyExtension\Redirects;
|
||||
|
||||
use TYPO3\CMS\Redirects\Event\ModifyRedirectManagementControllerViewDataEvent;
|
||||
|
||||
final class MyEventListener {
|
||||
|
||||
public function __invoke(
|
||||
ModifyRedirectManagementControllerViewDataEvent $event
|
||||
): void {
|
||||
$hosts = $event->getHosts();
|
||||
|
||||
// remove wildcard host from list
|
||||
$hosts = array_filter($hosts, static fn ($host) => $host['name'] !== '*');
|
||||
|
||||
// update changed hosts list
|
||||
$event->setHosts($hosts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
With the new :php:`ModifyRedirectManagementControllerViewDataEvent`, it is
|
||||
now possible to modify view data or inject further data to the view for the
|
||||
management view of redirects.
|
||||
|
||||
.. index:: PHP-API, ext:redirects
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-99803-1675373908:
|
||||
|
||||
===========================================================
|
||||
Feature: #99803 - New PSR-14 BeforeRedirectMatchDomainEvent
|
||||
===========================================================
|
||||
|
||||
See :issue:`99803`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A new PSR-14 event :php:`\TYPO3\CMS\Redirects\Event\BeforeRedirectMatchDomainEvent`
|
||||
is introduced to the :php:`\TYPO3\CMS\Redirects\Service\RedirectService`, allowing extension authors to implement a
|
||||
custom redirect matching upon the loaded redirects or return matched redirect
|
||||
record from other sources.
|
||||
|
||||
This event features following methods:
|
||||
|
||||
- :php:`getDomain()`: Returns the domain for which redirects should be
|
||||
checked for, "*" for all domains.
|
||||
- :php:`getPath()`: Returns the path which should be checked.
|
||||
- :php:`getQuery()`: Returns the query part which should be checked.
|
||||
- :php:`getMatchDomainName()`: Returns current check domain name.
|
||||
- :php:`getMatchedRedirect()`: Returns the matched :sql:`sys_redirect` record,
|
||||
set by another event listener or null.
|
||||
- :php:`setMatchedRedirect()`: Can be used to clear prior matched redirect
|
||||
by setting it to :php:`null` or set a matched :sql:`sys_redirect` record.
|
||||
|
||||
.. note::
|
||||
|
||||
Full :sql:`sys_redirect` record must be set using `setMatchedRedirect()` method.
|
||||
Otherwise later Core code would fail, as it expects, for example, the uid of the record
|
||||
to set the `X-Redirect-By` response header. Therefore, the `getMatchedRedirect()`
|
||||
method returns null or a full :sql:`sys_redirect` record.
|
||||
|
||||
.. note::
|
||||
|
||||
The :php:`BeforeRedirectMatchDomainEvent` is dispatched before cached redirects
|
||||
are retrieved. That means, that the event does not contain any :sql:`sys_redirect`
|
||||
records. Internal redirect cache may vanish eventually if possible. Therefore,
|
||||
it is left out to avoid a longer bound state to the event by properly deprecate it.
|
||||
|
||||
Example:
|
||||
--------
|
||||
|
||||
Registration of the event listener:
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: EXT:my_extension/Configuration/Services.yaml
|
||||
|
||||
MyVendor\MyExtension\Redirects\MyEventListener:
|
||||
tags:
|
||||
- name: event.listener
|
||||
identifier: 'my-extension/before-redirect-match-domain'
|
||||
|
||||
The corresponding event listener class:
|
||||
|
||||
.. code-block:: php
|
||||
:caption: EXT:my_extension/Classes/Redirects/MyEventListener.php
|
||||
|
||||
namespace MyVendor\MyExtension\Redirects;
|
||||
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Redirects\Event\BeforeRedirectMatchDomainEvent;
|
||||
|
||||
final class MyEventListener
|
||||
{
|
||||
public function __invoke(BeforeRedirectMatchDomainEvent $event): void
|
||||
{
|
||||
$matchedRedirectRecord = $this->customRedirectMatching($event);
|
||||
if ($matchedRedirectRecord !== null) {
|
||||
$event->setMatchedRedirect($matchedRedirectRecord);
|
||||
}
|
||||
}
|
||||
|
||||
private function customRedirectMatching(
|
||||
BeforeRedirectMatchDomainEvent $event
|
||||
): ?array {
|
||||
|
||||
// @todo Implement custom redirect record loading and matching. If
|
||||
// a redirect based on custom logic is determined, return the
|
||||
// :sql:`sys_redirect` tables conform redirect record.
|
||||
|
||||
// Note: Below is simplified example code with no real value.
|
||||
$record = BackendUtility::getRecord('sys_redirect', 123);
|
||||
|
||||
// Do custom matching logic against the record and return matched
|
||||
// record - if there is one.
|
||||
if ($record
|
||||
&& /* custom condition against the record */
|
||||
) {
|
||||
return $record;
|
||||
}
|
||||
|
||||
// return null to indicate that no matched redirect could be found
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
With the new :php:`BeforeRedirectMatchDomainEvent` it is now possible to
|
||||
implement custom redirect matching methods before core matching is processed.
|
||||
|
||||
.. index:: PHP-API, ext:redirects
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-99834-1675612921:
|
||||
|
||||
=========================================================================
|
||||
Feature: #99834 - New PSR-14 AfterAutoCreateRedirectHasBeenPersistedEvent
|
||||
=========================================================================
|
||||
|
||||
See :issue:`99834`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A new PSR-14 event :php:`\TYPO3\CMS\Redirects\Event\AfterAutoCreateRedirectHasBeenPersistedEvent`
|
||||
is introduced, allowing extension authors to react on persisted auto-created redirects. This
|
||||
can be used to call external API or do other tasks based on the real persisted redirects.
|
||||
|
||||
.. note::
|
||||
|
||||
To handle later updates or react on manual created redirects in the backend
|
||||
module, available hooks of :php:`\TYPO3\CMS\Core\DataHandling\DataHandler`
|
||||
can be used.
|
||||
|
||||
Example:
|
||||
--------
|
||||
|
||||
Registration of the event listener:
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: EXT:my_extension/Configuration/Services.yaml
|
||||
|
||||
MyVendor\MyExtension\Redirects\MyEventListener:
|
||||
tags:
|
||||
- name: event.listener
|
||||
identifier: 'my-extension/after-auto-create-redirect-has-been-persisted'
|
||||
|
||||
The corresponding event listener class:
|
||||
|
||||
.. code-block:: php
|
||||
:caption: EXT:my_extension/Classes/Redirects/MyEventListener.php
|
||||
|
||||
namespace MyVendor\MyExtension\Redirects;
|
||||
|
||||
use TYPO3\CMS\Redirects\Event\AfterAutoCreateRedirectHasBeenPersistedEvent;
|
||||
use TYPO3\CMS\Redirects\RedirectUpdate\PlainSlugReplacementRedirectSource;
|
||||
|
||||
class MyEventListener {
|
||||
|
||||
public function __invoke(
|
||||
AfterAutoCreateRedirectHasBeenPersistedEvent $event
|
||||
): void {
|
||||
$redirectUid = $event->getRedirectRecord()['uid'] ?? null;
|
||||
if ($redirectUid === null
|
||||
&& !($event->getSource() instanceof PlainSlugReplacementRedirectSource)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Implement code what should be done with this information. E.g.
|
||||
// write to another table, call a rest api or similar. Find your
|
||||
// use-case.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
With the new :php:`AfterAutoCreateRedirectHasBeenPersistedEvent`, it is now possible
|
||||
to react on persisted auto-created redirects. Manually created redirects can be handled
|
||||
by using one of the available :php:`\TYPO3\CMS\Core\DataHandling\DataHandler` hooks,
|
||||
not suitable for auto-created redirects.
|
||||
|
||||
.. index:: PHP-API, ext:redirects
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-99834-1675612872:
|
||||
|
||||
================================================================================
|
||||
Feature: #99834 - New PSR-14 ModifyAutoCreateRedirectRecordBeforePersistingEvent
|
||||
================================================================================
|
||||
|
||||
See :issue:`99834`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A new PSR-14 :php:`\TYPO3\CMS\Redirects\Event\ModifyAutoCreateRedirectRecordBeforePersistingEvent`
|
||||
is introduced, allowing extension authors to modify the redirect record before it is persisted to
|
||||
the database. This can be used to change values based on circumstances, for example, like
|
||||
different sub tree settings, not covered by the Core site configuration. Another use-case
|
||||
could be to write data to additional :sql:`sys_redirect` columns added by a custom
|
||||
extension for later use.
|
||||
|
||||
.. note::
|
||||
|
||||
To handle later updates or react on manually created redirects in the backend
|
||||
module, available hooks of :php:`\TYPO3\CMS\Core\DataHandling\DataHandler`
|
||||
can be used.
|
||||
|
||||
Example:
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: EXT:my_extension/Configuration/Services.yaml
|
||||
|
||||
MyVendor\MyExtension\Redirects\MyEventListener:
|
||||
tags:
|
||||
- name: event.listener
|
||||
identifier: 'my-extension/modify-auto-create-redirect-record-before-persisting'
|
||||
|
||||
The corresponding event listener class:
|
||||
|
||||
.. code-block:: php
|
||||
:caption: EXT:my_extension/Classes/Redirects/MyEventListener.php
|
||||
|
||||
namespace MyVendor\MyExtension\Redirects;
|
||||
|
||||
use TYPO3\CMS\Redirects\Event\ModifyAutoCreateRedirectRecordBeforePersistingEvent;
|
||||
use TYPO3\CMS\Redirects\RedirectUpdate\PlainSlugReplacementRedirectSource;
|
||||
|
||||
final class MyEventListener {
|
||||
|
||||
public function __invoke(
|
||||
ModifyAutoCreateRedirectRecordBeforePersistingEvent $event
|
||||
): void {
|
||||
|
||||
// only work on plain slug replacement redirect sources.
|
||||
if (!($event->getSource() instanceof PlainSlugReplacementRedirectSource)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get prepared redirect record and change some values
|
||||
$record = $event->getRedirectRecord();
|
||||
|
||||
// override the status code, eventually to another value than
|
||||
// configured in the site configuration
|
||||
$record['status_code'] = 307;
|
||||
|
||||
// Set value to a field extended by a custom extension, to persist
|
||||
// additional data to the redirect record.
|
||||
$record['custom_field_added_by_a_extension']
|
||||
= 'page_' . $event->getSlugRedirectChangeItem()->getPageId();
|
||||
|
||||
// Update changed record in event to ensure changed values are saved.
|
||||
$event->setRedirectRecord($record);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
With the new :php:`ModifyAutoCreateRedirectRecordBeforePersistingEvent`, it is now
|
||||
possible to modify the auto-create redirect record before it is persisted to the database.
|
||||
Manually created redirects or updated redirects can be handled by using the well-known
|
||||
:php:`\TYPO3\CMS\Core\DataHandling\DataHandler` and the available hooks.
|
||||
|
||||
.. index:: PHP-API, ext:redirects
|
||||
@@ -0,0 +1,36 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-99861-1675757796:
|
||||
|
||||
==================================================
|
||||
Feature: #99861 - Add tile view to element browser
|
||||
==================================================
|
||||
|
||||
See :issue:`99861`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The file list is the default implementation for TYPO3 to navigate and
|
||||
manage assets. This patch extends the usage of the file list to the
|
||||
element browser, the build-in component to select the assets for file
|
||||
fields and folder fields in the backend.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
The rendering of files and folder now deliver a unified experience and
|
||||
allow the user to use the tile view to select assets.
|
||||
|
||||
The search within the file browser now respects the selected folder and
|
||||
searches all subfolders for the provided search term.
|
||||
|
||||
To have an even more reliable experience, the user will now always start
|
||||
the selection process in the root folder of the default storage.
|
||||
|
||||
Resource tiles are now adapting to the surrounding container instead of
|
||||
the viewport, to make better use of the available space.
|
||||
|
||||
The file list now holds all related code to the file and folder browser.
|
||||
|
||||
.. index:: Backend, FAL, ext:filelist
|
||||
@@ -0,0 +1,29 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-99874-1678720364:
|
||||
|
||||
==============================================================
|
||||
Feature: #99874 - Edit task groups within the Scheduler module
|
||||
==============================================================
|
||||
|
||||
See :issue:`99874`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Task groups can be managed in the backend module itself. Users can create, update and
|
||||
delete task groups within the :guilabel:`Scheduler` module. Sorting is done via drag&drop (drag the panel header)
|
||||
and inline-style editing is used to change the title name. Only empty groups may be deleted.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Users may edit groups in the :guilabel:`Scheduler` module.
|
||||
|
||||
.. note::
|
||||
|
||||
The group's description has never been displayed in the :guilabel:`Scheduler` module and has been
|
||||
deprecated. Editing the description is and has always been only possible via the :guilabel:`List` module.
|
||||
|
||||
|
||||
.. index:: ext:scheduler
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-99976-1676660028:
|
||||
|
||||
===============================================================================
|
||||
Feature: #99976 - Introduce ignoreFlexFormSettingsIfEmpty Extbase configuration
|
||||
===============================================================================
|
||||
|
||||
See :issue:`99976`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
It is now possible to exclude empty FlexForm settings from being merged into
|
||||
Extbase extension settings. Extension authors and integrators can use the new
|
||||
Extbase TypoScript configuration :typoscript:`ignoreFlexFormSettingsIfEmpty`
|
||||
to define FlexForm settings, which will be ignored in the merge process of the
|
||||
extension settings, if their value is considered empty (either an empty string or a
|
||||
string containing `0`).
|
||||
|
||||
In the following example, :xml:`settings.showForgotPassword` and
|
||||
:xml:`settings.showPermaLogin` from FlexForm will not be merged into extension
|
||||
settings, if the individual value is empty:
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
plugin.tx_felogin_login.ignoreFlexFormSettingsIfEmpty = showForgotPassword,showPermaLogin
|
||||
|
||||
If an extension already defined :typoscript:`ignoreFlexFormSettingsIfEmpty`,
|
||||
integrators are advised to use :typoscript:`addToList` or
|
||||
:typoscript:`removeFromList` to modify existing settings as shown in the
|
||||
following example:
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
plugin.tx_felogin_login.ignoreFlexFormSettingsIfEmpty := removeFromList(showForgotPassword)
|
||||
plugin.tx_felogin_login.ignoreFlexFormSettingsIfEmpty := addToList(domains)
|
||||
|
||||
It is possible to define the :typoscript:`ignoreFlexFormSettingsIfEmpty`
|
||||
configuration globally for an extension using the
|
||||
:typoscript:`plugin.tx_extension` TypoScript configuration or for an individual
|
||||
plugin using the :typoscript:`plugin.tx_extension_plugin` TypoScript
|
||||
configuration.
|
||||
|
||||
Extension authors can use the new PSR-14 event
|
||||
:php:`\TYPO3\CMS\Extbase\Event\Configuration\BeforeFlexFormConfigurationOverrideEvent`
|
||||
to implement a FlexForm override process in a custom extension based on the original
|
||||
FlexForm configuration and the framework configuration.
|
||||
|
||||
Additionally, the new Extbase TypoScript configuration is used in EXT:felogin to
|
||||
ensure that empty FlexForm settings are not merged into extension settings.
|
||||
|
||||
Event example
|
||||
-------------
|
||||
|
||||
Register an event listener in your :file:`Services.yaml` file:
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: EXT:my_extension/Configuration/Services.yaml
|
||||
|
||||
MyVendor\MyExtension\FlexForm\EventListener\MyEventListener:
|
||||
tags:
|
||||
- name: event.listener
|
||||
identifier: 'my-extension/custom-absolute-path'
|
||||
|
||||
|
||||
Implement the event listener:
|
||||
|
||||
.. code-block:: php
|
||||
:caption: EXT:my_extension/Classes/FlexForm/EventListener/MyEventListener.php
|
||||
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MyVendor\MyExtension\FlexForm\EventListener;
|
||||
|
||||
use TYPO3\CMS\Extbase\Event\Configuration\BeforeFlexFormConfigurationOverrideEvent;
|
||||
|
||||
final class MyEventListener
|
||||
{
|
||||
public function __invoke(BeforeFlexFormConfigurationOverrideEvent $event): void
|
||||
{
|
||||
// Configuration from TypoScript
|
||||
$frameworkConfiguration = $event->getFrameworkConfiguration();
|
||||
|
||||
// Configuration from FlexForm
|
||||
$originalFlexFormConfiguration = $event->getOriginalFlexFormConfiguration();
|
||||
|
||||
// Currently merged configuration
|
||||
$flexFormConfiguration = $event->getFlexFormConfiguration();
|
||||
|
||||
// Implement custom logic
|
||||
$flexFormConfiguration['settings']['foo'] = 'set from event listener';
|
||||
$event->setFlexFormConfiguration($flexFormConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Empty FlexForm extension settings can now conditionally be excluded from the
|
||||
FlexForm configuration merge process.
|
||||
|
||||
Also, it is now possible again to use global TypoScript extension settings
|
||||
in EXT:felogin, which previously might have been overridden by empty FlexForm
|
||||
settings.
|
||||
|
||||
In addition, with the new :php:`BeforeFlexFormConfigurationOverrideEvent` it is
|
||||
now possible to further manipulate the merged configuration after standard
|
||||
override logic is applied.
|
||||
|
||||
.. index:: ext:extbase
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _important-100032-1677331239:
|
||||
|
||||
=====================================================================
|
||||
Important: #100032 - Add HTTP security headers for backend by default
|
||||
=====================================================================
|
||||
|
||||
See :issue:`100032`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The following HTTP security headers are now added by default for the TYPO3
|
||||
backend:
|
||||
|
||||
* `Strict-Transport-Security: max-age=31536000` (only if
|
||||
:php:`$GLOBALS[TYPO3_CONF_VARS][BE][lockSSL]` is active)
|
||||
* `X-Content-Type-Options: nosniff`
|
||||
* `Referrer-Policy: strict-origin-when-cross-origin`
|
||||
|
||||
The default HTTP security headers are configured globally in
|
||||
`$GLOBALS['TYPO3_CONF_VARS']['BE']['HTTP']['Response']['Headers']` and include
|
||||
a unique array key, so it is possible to individually unset/remove unwanted
|
||||
headers.
|
||||
|
||||
.. important::
|
||||
|
||||
TYPO3 websites, which already use custom HTTP headers for the TYPO3 backend,
|
||||
must ensure that individual HTTP security headers are not sent multiple
|
||||
times.
|
||||
|
||||
.. index:: Backend, ext:backend
|
||||
@@ -0,0 +1,48 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _important-100088-1677950866:
|
||||
|
||||
=========================================================
|
||||
Important: #100088 - Remove dbType json for TCA type user
|
||||
=========================================================
|
||||
|
||||
See :issue:`100088`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
With :issue:`99226` the `dbType=json` option has been added for
|
||||
TCA type `user`. After some reconsideration, it has been decided
|
||||
to drop this option again in favor of the dedicated TCA type `json`.
|
||||
Have a look to the according :ref:`changelog <feature-100088-1677965005>`
|
||||
for further information.
|
||||
|
||||
Since the `dbType` option has not been released in any LTS version yet,
|
||||
the option is dropped without further deprecation. Also no TCA migration
|
||||
is applied.
|
||||
|
||||
In case you make already use of this `dbType` in your custom extension,
|
||||
you need to migrate to the new TCA type.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// Before
|
||||
'myField' => [
|
||||
'config' => [
|
||||
'type' => 'user',
|
||||
'renderType' => 'myRenderType',
|
||||
'dbType' => 'json',
|
||||
],
|
||||
],
|
||||
|
||||
// After
|
||||
'myField' => [
|
||||
'config' => [
|
||||
'type' => 'json',
|
||||
'renderType' => 'myRenderType',
|
||||
],
|
||||
],
|
||||
|
||||
.. index:: Backend, PHP-API, TCA, ext:backend
|
||||
@@ -0,0 +1,23 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _important-100135-1678453394:
|
||||
|
||||
=========================================================
|
||||
Important: #100135 - Remove cookie warning in ext:felogin
|
||||
=========================================================
|
||||
|
||||
See :issue:`100135`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The cookie warning message in ext:felogin is never shown, since it depends on
|
||||
conditions, which will never be met. The cookie warning message can also be
|
||||
considered superfluous, since a similar message is already shown, if
|
||||
authentication was not successful.
|
||||
|
||||
Code affecting the non-working cookie warning message has therefore been
|
||||
removed from ext:felogin. TYPO3 users should remove code from custom templates,
|
||||
which depend on the `{cookieWarning}` variable.
|
||||
|
||||
.. index:: ext:felogin
|
||||
@@ -0,0 +1,54 @@
|
||||
:template: changelogOverview.html
|
||||
.. include:: /Includes.rst.txt
|
||||
.. _changelog-12-3:
|
||||
|
||||
============
|
||||
12.3 Changes
|
||||
============
|
||||
|
||||
**Table of contents**
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
Breaking Changes
|
||||
================
|
||||
|
||||
None since TYPO3 v12.0 release.
|
||||
|
||||
.. attention::
|
||||
|
||||
After TYPO3 v12.0, only new functionality with a solid migration path
|
||||
can be added on top, with aiming for as little as possible breaking changes
|
||||
after the initial v12.0 release on the way to LTS.
|
||||
|
||||
Features
|
||||
========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:titlesonly:
|
||||
:glob:
|
||||
|
||||
Feature-*
|
||||
|
||||
Deprecation
|
||||
===========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:titlesonly:
|
||||
:glob:
|
||||
|
||||
Deprecation-*
|
||||
|
||||
Important
|
||||
=========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:titlesonly:
|
||||
:glob:
|
||||
|
||||
Important-*
|
||||
Reference in New Issue
Block a user