Commit b1a52d3c authored by Christian Kuhn's avatar Christian Kuhn Committed by Benni Mack
Browse files

[!!!][TASK] Remove extbase ObjectManager

Remove main ObjectManager and Container classes plus
the v11 compatibility layers in various places.

composer rem doctrine/instantiator
composer rem doctrine/instantiator -d typo3/sysext/core --no-update

Resolves: #96208
Related: #94377
Related: #94370
Related: #94317
Related: #94619
Related: #94451
Related: #90803
Releases: main
Change-Id: I19590e73a562babebc1318cb343a512fc0d28e1d
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/72469

Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Stefan Bürk's avatarStefan Bürk <stefan@buerk.tech>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Stefan Bürk's avatarStefan Bürk <stefan@buerk.tech>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent 0a123e4f
......@@ -45,7 +45,6 @@
"doctrine/annotations": "^1.11",
"doctrine/dbal": "^2.13.5",
"doctrine/event-manager": "^1.0.0",
"doctrine/instantiator": "^1.4",
"doctrine/lexer": "^1.2.1",
"egulias/email-validator": "^3.1",
"enshrined/svg-sanitize": "^0.14.1",
......@@ -277,14 +276,9 @@
"classmap": [
"typo3/sysext/core/Tests/Unit/Core/Fixtures/test_extension/",
"typo3/sysext/core/Tests/Functional/Fixtures/",
"typo3/sysext/extbase/Tests/Unit/Object/Container/Fixtures/",
"typo3/sysext/extbase/Tests/UnitDeprecated/Object/Container/Fixtures/",
"typo3/sysext/extbase/Tests/Functional/Fixtures/",
"typo3/sysext/extbase/Tests/Functional/Mvc/Controller/Fixture/",
"typo3/sysext/fluid/Tests/Functional/Fixtures/Extensions/fluid_test/Classes/"
],
"files": [
"typo3/sysext/extbase/Tests/Fixture/TxClassWithGettersAndSetters.php"
]
}
}
......@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "80d186577e150ee1f321136b4f61de64",
"content-hash": "77cbdb64178e6299cc10c4ce1c72c447",
"packages": [
{
"name": "bacon/bacon-qr-code",
......@@ -562,75 +562,6 @@
],
"time": "2020-05-29T18:28:51+00:00"
},
{
"name": "doctrine/instantiator",
"version": "1.4.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
"reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b",
"reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"doctrine/coding-standard": "^8.0",
"ext-pdo": "*",
"ext-phar": "*",
"phpbench/phpbench": "^0.13 || 1.0.0-alpha2",
"phpstan/phpstan": "^0.12",
"phpstan/phpstan-phpunit": "^0.12",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com",
"homepage": "https://ocramius.github.io/"
}
],
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
"homepage": "https://www.doctrine-project.org/projects/instantiator.html",
"keywords": [
"constructor",
"instantiate"
],
"support": {
"issues": "https://github.com/doctrine/instantiator/issues",
"source": "https://github.com/doctrine/instantiator/tree/1.4.0"
},
"funding": [
{
"url": "https://www.doctrine-project.org/sponsorship.html",
"type": "custom"
},
{
"url": "https://www.patreon.com/phpdoctrine",
"type": "patreon"
},
{
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
"type": "tidelift"
}
],
"time": "2020-11-10T18:47:58+00:00"
},
{
"name": "doctrine/lexer",
"version": "1.2.1",
......@@ -5859,6 +5790,75 @@
],
"time": "2021-07-31T17:03:58+00:00"
},
{
"name": "doctrine/instantiator",
"version": "1.4.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
"reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b",
"reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"doctrine/coding-standard": "^8.0",
"ext-pdo": "*",
"ext-phar": "*",
"phpbench/phpbench": "^0.13 || 1.0.0-alpha2",
"phpstan/phpstan": "^0.12",
"phpstan/phpstan-phpunit": "^0.12",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com",
"homepage": "https://ocramius.github.io/"
}
],
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
"homepage": "https://www.doctrine-project.org/projects/instantiator.html",
"keywords": [
"constructor",
"instantiate"
],
"support": {
"issues": "https://github.com/doctrine/instantiator/issues",
"source": "https://github.com/doctrine/instantiator/tree/1.4.0"
},
"funding": [
{
"url": "https://www.doctrine-project.org/sponsorship.html",
"type": "custom"
},
{
"url": "https://www.patreon.com/phpdoctrine",
"type": "patreon"
},
{
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
"type": "tidelift"
}
],
"time": "2020-11-10T18:47:58+00:00"
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.2.1",
......
......@@ -18,13 +18,9 @@ declare(strict_types=1);
namespace TYPO3\CMS\Belog\Tests\Unit\Domain\Repository;
use TYPO3\CMS\Belog\Domain\Repository\LogEntryRepository;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
use TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
/**
* Test case
*/
class LogEntryRepositoryTest extends UnitTestCase
{
/**
......@@ -37,7 +33,6 @@ class LogEntryRepositoryTest extends UnitTestCase
$subject = $this->getMockBuilder(LogEntryRepository::class)
->onlyMethods(['setDefaultQuerySettings'])
->addMethods(['getBackendUsers'])
->setConstructorArgs([$this->getMockBuilder(ObjectManagerInterface::class)->getMock()])
->getMock();
$subject->injectQuerySettings($querySettings);
$subject->expects(self::once())->method('setDefaultQuerySettings')->with($querySettings);
......
......@@ -18,13 +18,9 @@ declare(strict_types=1);
namespace TYPO3\CMS\Belog\Tests\Unit\Domain\Repository;
use TYPO3\CMS\Belog\Domain\Repository\WorkspaceRepository;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
use TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
/**
* Test case
*/
class WorkspaceRepositoryTest extends UnitTestCase
{
/**
......@@ -36,7 +32,6 @@ class WorkspaceRepositoryTest extends UnitTestCase
$querySettings->expects(self::atLeastOnce())->method('setRespectStoragePage')->with(false)->willReturn($querySettings);
$subject = $this->getMockBuilder(WorkspaceRepository::class)
->onlyMethods(['setDefaultQuerySettings'])
->setConstructorArgs([$this->getMockBuilder(ObjectManagerInterface::class)->getMock()])
->getMock();
$subject->injectQuerySettings($querySettings);
$subject->expects(self::once())->method('setDefaultQuerySettings')->with($querySettings);
......
......@@ -18,12 +18,8 @@ declare(strict_types=1);
namespace TYPO3\CMS\Beuser\Tests\Unit\Domain\Repository;
use TYPO3\CMS\Beuser\Domain\Repository\BackendUserRepository;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
/**
* Test case
*/
class BackendUserRepositoryTest extends UnitTestCase
{
/**
......@@ -31,7 +27,6 @@ class BackendUserRepositoryTest extends UnitTestCase
*/
public function classCanBeInstantiated(): void
{
$objectManager = $this->createMock(ObjectManagerInterface::class);
new BackendUserRepository($objectManager);
new BackendUserRepository();
}
}
......@@ -31,6 +31,12 @@ The following PHP classes that have previously been marked as deprecated for v11
- :php:`\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext`
- :php:`\TYPO3\CMS\Extbase\Mvc\View\AbstractView`
- :php:`\TYPO3\CMS\Extbase\Mvc\View\EmptyView`
- :php:`\TYPO3\CMS\Extbase\Object\Container\Container`
- :php:`\TYPO3\CMS\Extbase\Object\Container\Exception\UnknownObjectException`
- :php:`\TYPO3\CMS\Extbase\Object\Exception`
- :php:`\TYPO3\CMS\Extbase\Object\Exception\CannotBuildObjectException`
- :php:`\TYPO3\CMS\Extbase\Object\Exception\CannotReconstituteObjectException`
- :php:`\TYPO3\CMS\Extbase\Object\ObjectManager`
- :php:`\TYPO3\CMS\Extbase\Service\EnvironmentService`
- :php:`\TYPO3\CMS\Extbase\SignalSlot\Dispatcher`
- :php:`\TYPO3\CMS\Extbase\SignalSlot\Exception\InvalidSlotException`
......@@ -43,9 +49,18 @@ The following PHP interfaces that have previously been marked as deprecated for
- :php:`\TYPO3\CMS\Core\Resource\Hook\FileDumpEIDHookInterface`
- :php:`\TYPO3\CMS\Core\Utility\File\ExtendedFileUtilityProcessDataHookInterface`
- :php:`\TYPO3\CMS\Extbase\Mvc\View\ViewInterface`
- :php:`\TYPO3\CMS\Extbase\Object\ObjectManagerInterface`
- :php:`\TYPO3\CMS\Extbase\Persistence\ForwardCompatibleQueryInterface`
- :php:`\TYPO3\CMS\Extbase\Persistence\ForwardCompatibleQueryResultInterface`
- :php:`\TYPO3\CMS\Filelist\FileListEditIconHookInterface'`
- :php:`\TYPO3\CMS\Recordlist\RecordList\RecordListHookInterface`
The following PHP interfaces changed:
- :php:`\TYPO3\CMS\Extbase\Persistence\QueryInterface` (method :php:`setType()` added)
- :php:`\TYPO3\CMS\Extbase\Persistence\QueryResultInterface` (method :php:`setQuery()` added)
- :php:`\TYPO3\CMS\Form\Domain\Finishers\FinisherInterface` (method :php:`setFinisherIdentifier()` added)
The following PHP class aliases that have previously been marked as deprecated for v11 and were now removed:
* :php:`Full\Class\Name`
......
......@@ -33,7 +33,6 @@
"doctrine/annotations": "^1.11",
"doctrine/dbal": "^2.13.5",
"doctrine/event-manager": "^1.0.0",
"doctrine/instantiator": "^1.4",
"doctrine/lexer": "^1.2.1",
"egulias/email-validator": "^3.1",
"enshrined/svg-sanitize": "^0.14.1",
......
......@@ -44,7 +44,6 @@ use TYPO3\CMS\Extbase\Mvc\View\GenericViewResolver;
use TYPO3\CMS\Extbase\Mvc\View\JsonView;
use TYPO3\CMS\Extbase\Mvc\View\ViewResolverInterface;
use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
use TYPO3\CMS\Extbase\Property\Exception\TargetNotFoundException;
use TYPO3\CMS\Extbase\Property\PropertyMapper;
use TYPO3\CMS\Extbase\Reflection\ReflectionService;
......@@ -139,13 +138,6 @@ abstract class ActionController implements ControllerInterface
*/
protected $request;
/**
* @var ObjectManagerInterface
* @internal only to be used within Extbase, not part of TYPO3 Core API.
* @deprecated since v11, will be removed in v12
*/
protected $objectManager;
/**
* @var \TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder
*/
......@@ -209,19 +201,6 @@ abstract class ActionController implements ControllerInterface
{
$this->configurationManager = $configurationManager;
$this->settings = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS);
}
/**
* Injects the object manager
*
* @param ObjectManagerInterface $objectManager
* @internal only to be used within Extbase, not part of TYPO3 Core API.
* @deprecated since v11, will be removed in v12
*/
public function injectObjectManager(ObjectManagerInterface $objectManager)
{
$this->objectManager = $objectManager;
// @todo: Move elsewhere
$this->arguments = GeneralUtility::makeInstance(Arguments::class);
}
......
......@@ -27,7 +27,6 @@ use TYPO3\CMS\Extbase\Mvc\Controller\ControllerInterface;
use TYPO3\CMS\Extbase\Mvc\Exception\InfiniteLoopException;
use TYPO3\CMS\Extbase\Mvc\Exception\InvalidControllerException;
use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
/**
* Dispatches requests to the controller which was specified by the request and
......@@ -36,12 +35,6 @@ use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
*/
class Dispatcher implements SingletonInterface
{
/**
* @var ObjectManagerInterface A reference to the object manager
* @deprecated since v11, will be removed in v12
*/
protected $objectManager;
/**
* @var ContainerInterface
*/
......@@ -60,17 +53,13 @@ class Dispatcher implements SingletonInterface
/**
* Constructs the global dispatcher
*
* @param ObjectManagerInterface $objectManager A reference to the object manager
* @param ContainerInterface $container
* @param EventDispatcherInterface $eventDispatcher
*/
public function __construct(
ObjectManagerInterface $objectManager,
ContainerInterface $container,
EventDispatcherInterface $eventDispatcher
) {
// @deprecated since v11, will be removed in v12
$this->objectManager = $objectManager;
$this->container = $container;
$this->eventDispatcher = $eventDispatcher;
}
......@@ -129,12 +118,7 @@ class Dispatcher implements SingletonInterface
protected function resolveController(RequestInterface $request)
{
$controllerObjectName = $request->getControllerObjectName();
if ($this->container->has($controllerObjectName)) {
$controller = $this->container->get($controllerObjectName);
} else {
// @deprecated since v11, will be removed in v12.
$controller = $this->objectManager->get($controllerObjectName);
}
$controller = $this->container->get($controllerObjectName);
if (!$controller instanceof ControllerInterface) {
throw new InvalidControllerException(
'Invalid controller "' . $request->getControllerObjectName() . '". The controller must implement the TYPO3\\CMS\\Extbase\\Mvc\\Controller\\ControllerInterface.',
......
......@@ -18,8 +18,6 @@ declare(strict_types=1);
namespace TYPO3\CMS\Extbase\Mvc\View;
use Psr\Container\ContainerInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3Fluid\Fluid\View\ViewInterface;
/**
......@@ -50,14 +48,8 @@ class GenericViewResolver implements ViewResolverInterface
public function resolve(string $controllerObjectName, string $actionName, string $format): ViewInterface
{
if ($this->container->has($this->defaultViewClass)) {
/** @var ViewInterface $view */
$view = $this->container->get($this->defaultViewClass);
return $view;
}
// @deprecated since v11, will be removed with 12. Fallback if extensions provide no proper Services.yaml. Drop together with if condition above in v12.
/** @var ViewInterface $view */
$view = GeneralUtility::makeInstance(ObjectManager::class)->get($this->defaultViewClass);
$view = $this->container->get($this->defaultViewClass);
return $view;
}
}
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\Extbase\Object\Container;
use Doctrine\Instantiator\Instantiator;
use Doctrine\Instantiator\InstantiatorInterface;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use TYPO3\CMS\Core\Core\ClassLoadingInformation;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\Exception;
use TYPO3\CMS\Extbase\Object\Exception\CannotBuildObjectException;
use TYPO3\CMS\Extbase\Reflection\ClassSchema;
use TYPO3\CMS\Extbase\Reflection\ReflectionService;
/**
* Internal TYPO3 Dependency Injection container
* @internal only to be used within Extbase, not part of TYPO3 Core API.
* @deprecated since v11, will be removed in v12. Use symfony DI and GeneralUtility::makeInstance() instead.
* See TYPO3 explained documentation for more information.
* Does not trigger_error since the ObjectManager->get() call does that.
* @template T
*/
class Container implements SingletonInterface, LoggerAwareInterface
{
use LoggerAwareTrait;
/**
* @var ContainerInterface
*/
private $psrContainer;
/**
* registered alternative implementations of a class
* e.g. used to know the class for an AbstractClass or a Dependency
*
* @var array
*/
private $alternativeImplementation;
/**
* @var InstantiatorInterface
*/
protected $instantiator;
/**
* holds references of singletons
*
* @var array
*/
private $singletonInstances = [];
/**
* Array of prototype objects currently being built, to prevent recursion.
*
* @var array
*/
private $prototypeObjectsWhichAreCurrentlyInstanciated;
/**
* @var ReflectionService
*/
private $reflectionService;
/**
* @param ContainerInterface $psrContainer
*/
public function __construct(ContainerInterface $psrContainer)
{
$this->psrContainer = $psrContainer;
}
/**
* Internal method to create the class instantiator, extracted to be mockable
*
* @return InstantiatorInterface
*/
protected function getInstantiator(): InstantiatorInterface
{
if ($this->instantiator == null) {
$this->instantiator = new Instantiator();
}
return $this->instantiator;
}
/**
* Main method which should be used to get an instance of the wished class
* specified by $className.
*
* @param string|class-string<T> $className
* @param array $givenConstructorArguments the list of constructor arguments as array
* @return object&T the built object
* @internal
*/
public function getInstance(string $className, array $givenConstructorArguments = []): object
{
$this->prototypeObjectsWhichAreCurrentlyInstanciated = [];
return $this->getInstanceInternal($className, ...$givenConstructorArguments);
}
/**
* Create an instance of $className without calling its constructor
*
* @param string|class-string<T> $className
* @return object&T
*/
public function getEmptyObject(string $className): object
{
$className = $this->getImplementationClassName($className);
$classSchema = $this->getReflectionService()->getClassSchema($className);
$object = $this->getInstantiator()->instantiate($className);
$this->injectDependencies($object, $classSchema);
$this->initializeObject($object);
return $object;
}
/**
* Internal implementation for getting a class.
*
* @param string|class-string<T> $className
* @param array<int,mixed> $givenConstructorArguments the list of constructor arguments as array
* @throws \TYPO3\CMS\Extbase\Object\Exception
* @throws \TYPO3\CMS\Extbase\Object\Exception\CannotBuildObjectException
* @return object&T the built object
*/
protected function getInstanceInternal(string $className, ...$givenConstructorArguments): object
{
if ($className === ContainerInterface::class) {
return $this->psrContainer;
}
$className = $this->getImplementationClassName($className);
if ($givenConstructorArguments === [] && $this->psrContainer->has($className)) {
$instance = $this->psrContainer->get($className);
if (!is_object($instance)) {
throw new Exception('PSR-11 container returned non object for class name "' . $className . '".', 1562240407);
}
return $instance;
}
$className = ClassLoadingInformation::getClassNameForAlias($className);
if (isset($this->singletonInstances[$className])) {
if (!empty($givenConstructorArguments)) {
throw new Exception('Object "' . $className . '" fetched from singleton cache, thus, explicit constructor arguments are not allowed.', 1292857934);
}
return $this->singletonInstances[$className];
}
$classSchema = $this->getReflectionService()->getClassSchema($className);
$classIsSingleton = $classSchema->isSingleton();
if (!$classIsSingleton) {
if (array_key_exists($className, $this->prototypeObjectsWhichAreCurrentlyInstanciated) !== false) {
throw new CannotBuildObjectException('Cyclic dependency in prototype object, for class "' . $className . '".', 1295611406);
}
$this->prototypeObjectsWhichAreCurrentlyInstanciated[$className] = true;
}
$instance = $this->instanciateObject($classSchema, ...$givenConstructorArguments);
$this->injectDependencies($instance, $classSchema);
$this->initializeObject($instance);
if (!$classIsSingleton) {
unset($this->prototypeObjectsWhichAreCurrentlyInstanciated[$className]);
}
return $instance;
}
/**
* Instantiates an object, possibly setting the constructor dependencies.
* Additionally, directly registers all singletons in the singleton registry,
* such that circular references of singletons are correctly instantiated.
*
* @param ClassSchema $classSchema
* @param array<int,mixed> $givenConstructorArguments
* @throws \TYPO3\CMS\Extbase\Object\Exception
* @return object the new instance
*/
protected function instanciateObject(ClassSchema $classSchema, ...$givenConstructorArguments): object
{
$className = $classSchema->getClassName();
$classIsSingleton = $classSchema->isSingleton();
if ($classIsSingleton && !empty($givenConstructorArguments)) {
throw new Exception('Object "' . $className . '" has explicit constructor arguments but is a singleton; this is not allowed.', 1292858051);