Commit 14805bdf authored by Christian Kuhn's avatar Christian Kuhn
Browse files

[TASK] Deprecate extbase ObjectManager->getEmptyObject()

ObjectManager->getEmptyObject() is only used in extbase
persistence DataMapper when domain objects are "thawed":
An existing DB row is fetched and a model object is
created from it.

From extbase PoV, a domain object lifecycle is "creation"
("own a new car"), then eventually "freezing" it in DB,
"thawing" it from DB to update it's state ("washed today,
it's now clean"), and eventually deletion ("brought to
scrapyard, don't own it anymore").

Extbase now says that "thawing" and "creation" are two
different things and thus decided that programmatically,
__construct() on thawed objects should NOT be called,
because, well, it's not new, just thawed! Don't assume
__wakeup() is called instead, though: It's not.

Extbase of course has to hop through quite some loops
to violate this PHP language construct. It even needs
the 3rd party dependency doctrine/instantiator to achieve
suppressing __construct() call, since the previous
'unserialize hack' broke somewhere during PHP 5 times.

Additionally, even though extbase Domain Model objects
*should* be plain old PHP objects, they still allow
inject* methods and are dependency injection aware.

This is a problem when moving away from ObjectManager
towards symfony DI, because symfony does not support
this creative extbase view of supressing __construct()
when instantiating objects.

We can't get rid of this easily in extbase, though.
There is no good way to deprecation-log this behavior. A
feature toggle seems to be overkill - probably not too
many extbase devs are aware of this implementation detail
in the first place, and the impact if __construct() is
properly called when an object is thawed should be relatively
small: First, models are usually relatively stupid in extbase
(which is good, they should be), and if they have a
__construct() method at all, chances are, everything that is
done there is overriden during the following mapping process
anyways.

We thus decided against a feature toggle for this. Instead,
we *keep* the current instantiation logic in v11, just
mark the code places as deprecated, configure the extension
scanner to look for additional getEmptyObject() calls in
extensions, and add a depreation reST file pointing out the
situation and stating __construct() will be called in v12
for thawed objects.

Resolves: #94377
Related: #90803
Releases: master
Change-Id: Ied3da8b9d885be2f635b9bc6c66b37fc9825decc
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/69520


Tested-by: Jochen's avatarJochen <rothjochen@gmail.com>
Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Daniel Goerz's avatarDaniel Goerz <daniel.goerz@posteo.de>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Jochen's avatarJochen <rothjochen@gmail.com>
Reviewed-by: Daniel Goerz's avatarDaniel Goerz <daniel.goerz@posteo.de>
Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
parent 1b17327d
.. include:: ../../Includes.txt
===========================================================
Deprecation: #94377 - extbase ObjectManager->getEmptyObject
===========================================================
See :issue:`94377`
Description
===========
Extbase has the odd behavior that :php:`DomainObjectInterface` objects
- typically classes in :file:`Classes/Domain/Model` of extbase enabled
extensions - don't call :php:`__construct` when the persistence layer
"thaws" a model from database - typically when a extbase
:php:`Domain/Repository` uses a :php:`->findBy*` method.
As a side-effect of switching away from extbase :php:`ObjectManager` towards
symfony based dependency injection, this behavior will change in core v12:
Method :php:`__construct()` will be called in v12 when the :php:`DataMapper`
creates model instances from database rows.
Impact
======
There is no impact in core v11 and no deprecation log entry is raised.
However, extension developers *should* prepare toward this change in v11
to avoid any impact of a breaking change in v12.
Affected Installations
======================
Extbase extensions having domain models that implement :php:`__construct()`
are affected. It is rather unlikely this has any impact on the behavior
of the extension, though.
Additionally, calls to API method
:php:`TYPO3\CMS\Extbase\Object\ObjectManager->getEmptyObject()` should be
avoided since it will vanish in v12. The vast majority of extensions will
not do this, though. The extension scanner will find candidates.
Migration
=========
No migration possible. Simply expect that :php:`__construct()` of a domain
model will be called in v12 when a domain repository :php:`findBy` method
directly or indirectly reconstitutes a model object from a database row.
.. index:: PHP-API, FullyScanned, ext:extbase
......@@ -119,6 +119,8 @@ class ObjectManager implements ObjectManagerInterface
*
* @param string $className
* @return object
* @deprecated since v11, will be removed in v12. Does NOT log, has a v11 deprecation.rst file.
* Used in DataMapper, will be removed as breaking change in v12. Also drop doctrine/instantiator.
*/
public function getEmptyObject(string $className): object
{
......
......@@ -201,6 +201,7 @@ class DataMapper
throw new CannotReconstituteObjectException('Cannot create empty instance of the class "' . $className
. '" because it does not implement the TYPO3\\CMS\\Extbase\\DomainObject\\DomainObjectInterface.', 1234386924);
}
// @deprecated since v11, will be removed in v12. Change to makeInstance(), so v12 will call __construct() on thawed domain objects!
$object = $this->objectManager->getEmptyObject($className);
return $object;
}
......
......@@ -4830,4 +4830,11 @@ return [
'Deprecation-94228-DeprecateExtbaseRequestGetRequestUri.rst'
],
],
'TYPO3\CMS\Extbase\Object\ObjectManager->getEmptyObject' => [
'numberOfMandatoryArguments' => 1,
'maximumNumberOfArguments' => 1,
'restFiles' => [
'Deprecation-94377-ExtbaseObjectManager-getEmptyObject.rst'
],
],
];
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment