Skip to content

Commit

Permalink
[TASK] Allow Doctrine/DBAL 2.13
Browse files Browse the repository at this point in the history
This change allows composer-based installations to
support Doctrine DBAL 2.13 in order to ease the upgrades.

The mono-repo (tarballs / non-composer-mode) still uses
Doctrine DBAL 2.10 to ensure the old return types are still
working properly within Doctrine DBAL.

Used composer commands:
* composer req doctrine/dbal:"~2.10.0 || ~2.11.2 || ~2.13.1"
* composer req doctrine/dbal:"~2.10.0 || ~2.11.2 || ~2.13.1" -d typo3/sysext/core --no-update
* composer req doctrine/dbal:"~2.10.0 || ~2.11.2 || ~2.13.1" -d typo3/sysext/install --no-update
* composer req doctrine/dbal:"~2.10.0 || ~2.11.2 || ~2.13.1" -d typo3/sysext/redirects --no-update

This change also adds the compatibility changes
made in the main branch via #93985 of commit
32b508b

Resolves: #94078
Related: #93985
Releases: 10.4
Change-Id: I74ddd19068b0e45e0c6b89218a96eda6d931ffc1
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/69055
Tested-by: core-ci <typo3@b13.com>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Oliver Hader <oliver.hader@typo3.org>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>
  • Loading branch information
bmack authored and ohader committed May 6, 2021
1 parent e173a12 commit 76c5d9d
Show file tree
Hide file tree
Showing 10 changed files with 203 additions and 121 deletions.
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -40,7 +40,7 @@
"ext-xml": "*",
"cogpowered/finediff": "~0.3.1",
"doctrine/annotations": "^1.7",
"doctrine/dbal": "~2.10.0 || ~2.11.2",
"doctrine/dbal": "~2.10.0 || ~2.11.2 || ~2.13.1",
"doctrine/instantiator": "^1.1",
"doctrine/lexer": "^1.0",
"egulias/email-validator": "^2.1",
Expand Down
2 changes: 1 addition & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

100 changes: 76 additions & 24 deletions typo3/sysext/core/Tests/Unit/Database/Query/QueryBuilderTest.php
Expand Up @@ -17,6 +17,7 @@

namespace TYPO3\CMS\Core\Tests\Unit\Database\Query;

use Doctrine\DBAL\ForwardCompatibility\Result;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\Platforms\OraclePlatform;
Expand Down Expand Up @@ -972,8 +973,13 @@ public function queryRestrictionsAreAddedForSelectOnExecute(): void
->where('uid=1');

$expectedSQL = 'SELECT * FROM pages WHERE (uid=1) AND ((pages.deleted = 0) AND (pages.hidden = 0))';
$this->connection->executeQuery($expectedSQL, Argument::cetera())
->shouldBeCalled();
if (class_exists(Result::class)) {
$this->connection->executeQuery($expectedSQL, Argument::cetera())
->willReturn($this->prophesize(Result::class)->reveal());
} else {
$this->connection->executeQuery($expectedSQL, Argument::cetera())
->shouldBeCalled();
}

$subject->execute();
}
Expand Down Expand Up @@ -1019,8 +1025,14 @@ public function queryRestrictionsAreAddedForCountOnExecute(): void
->where('uid=1');

$expectedSQL = 'SELECT COUNT(uid) FROM pages WHERE (uid=1) AND ((pages.deleted = 0) AND (pages.hidden = 0))';
$this->connection->executeQuery($expectedSQL, Argument::cetera())
->shouldBeCalled();

if (class_exists(Result::class)) {
$this->connection->executeQuery($expectedSQL, Argument::cetera())
->willReturn($this->prophesize(Result::class)->reveal());
} else {
$this->connection->executeQuery($expectedSQL, Argument::cetera())
->shouldBeCalled();
}

$subject->execute();
}
Expand Down Expand Up @@ -1113,16 +1125,27 @@ public function queryRestrictionsAreReevaluatedOnSettingsChangeForExecute(): voi
$subject->getRestrictions()->removeAll()->add(new DeletedRestriction());

$expectedSQL = 'SELECT * FROM pages WHERE (uid=1) AND (pages.deleted = 0)';
$this->connection->executeQuery($expectedSQL, Argument::cetera())
->shouldBeCalled();

if (class_exists(Result::class)) {
$this->connection->executeQuery($expectedSQL, Argument::cetera())
->willReturn($this->prophesize(Result::class)->reveal());
} else {
$this->connection->executeQuery($expectedSQL, Argument::cetera())
->shouldBeCalled();
}

$subject->execute();

$subject->resetRestrictions();

$expectedSQL = 'SELECT * FROM pages WHERE (uid=1) AND ((pages.deleted = 0) AND (pages.hidden = 0))';
$this->connection->executeQuery($expectedSQL, Argument::cetera())
->shouldBeCalled();
if (class_exists(Result::class)) {
$this->connection->executeQuery($expectedSQL, Argument::cetera())
->willReturn($this->prophesize(Result::class)->reveal());
} else {
$this->connection->executeQuery($expectedSQL, Argument::cetera())
->shouldBeCalled();
}

$subject->execute();
}
Expand Down Expand Up @@ -1497,10 +1520,18 @@ public function limitRestrictionsToTablesLimitsRestrictionsInTheContainerToTheGi
)
->where($expressionBuilder->eq('uid', 1));

$this->connection->executeQuery(
'SELECT * FROM pages LEFT JOIN tt_content content ON pages.uid = content.pid WHERE (uid = 1) AND ((pages.deleted = 0) AND (pages.hidden = 0))',
Argument::cetera()
)->shouldBeCalled();
if (class_exists(Result::class)) {
$this->connection->executeQuery(
'SELECT * FROM pages LEFT JOIN tt_content content ON pages.uid = content.pid WHERE (uid = 1) AND ((pages.deleted = 0) AND (pages.hidden = 0))',
Argument::cetera()
)
->willReturn($this->prophesize(Result::class)->reveal());
} else {
$this->connection->executeQuery(
'SELECT * FROM pages LEFT JOIN tt_content content ON pages.uid = content.pid WHERE (uid = 1) AND ((pages.deleted = 0) AND (pages.hidden = 0))',
Argument::cetera()
)->shouldBeCalled();
}

$subject->execute();
}
Expand Down Expand Up @@ -1548,10 +1579,17 @@ public function restrictionsCanStillBeRemovedAfterTheyHaveBeenLimitedToTables():
)
->where($expressionBuilder->eq('uid', 1));

$this->connection->executeQuery(
'SELECT * FROM pages LEFT JOIN tt_content content ON pages.uid = content.pid WHERE (uid = 1) AND (pages.hidden = 0)',
Argument::cetera()
)->shouldBeCalled();
if (class_exists(Result::class)) {
$this->connection->executeQuery(
'SELECT * FROM pages LEFT JOIN tt_content content ON pages.uid = content.pid WHERE (uid = 1) AND (pages.hidden = 0)',
Argument::cetera()
)->willReturn($this->prophesize(Result::class)->reveal());
} else {
$this->connection->executeQuery(
'SELECT * FROM pages LEFT JOIN tt_content content ON pages.uid = content.pid WHERE (uid = 1) AND (pages.hidden = 0)',
Argument::cetera()
)->shouldBeCalled();
}

$subject->execute();
}
Expand Down Expand Up @@ -1597,10 +1635,17 @@ public function restrictionsAreAppliedInJoinConditionForLeftJoins(): void
)
->where($expressionBuilder->eq('uid', 1));

$this->connection->executeQuery(
'SELECT * FROM pages LEFT JOIN tt_content content ON (pages.uid = content.pid) AND ((content.deleted = 0) AND (content.hidden = 0)) WHERE (uid = 1) AND ((pages.deleted = 0) AND (pages.hidden = 0))',
Argument::cetera()
)->shouldBeCalled();
if (class_exists(Result::class)) {
$this->connection->executeQuery(
'SELECT * FROM pages LEFT JOIN tt_content content ON (pages.uid = content.pid) AND ((content.deleted = 0) AND (content.hidden = 0)) WHERE (uid = 1) AND ((pages.deleted = 0) AND (pages.hidden = 0))',
Argument::cetera()
)->willReturn($this->prophesize(Result::class)->reveal());
} else {
$this->connection->executeQuery(
'SELECT * FROM pages LEFT JOIN tt_content content ON (pages.uid = content.pid) AND ((content.deleted = 0) AND (content.hidden = 0)) WHERE (uid = 1) AND ((pages.deleted = 0) AND (pages.hidden = 0))',
Argument::cetera()
)->shouldBeCalled();
}

$subject->execute();
}
Expand Down Expand Up @@ -1646,10 +1691,17 @@ public function restrictionsAreAppliedInJoinConditionForRightJoins(): void
)
->where($expressionBuilder->eq('uid', 1));

$this->connection->executeQuery(
'SELECT * FROM tt_content RIGHT JOIN pages pages ON (pages.uid = tt_content.pid) AND ((tt_content.deleted = 0) AND (tt_content.hidden = 0)) WHERE (uid = 1) AND ((pages.deleted = 0) AND (pages.hidden = 0))',
Argument::cetera()
)->shouldBeCalled();
if (class_exists(Result::class)) {
$this->connection->executeQuery(
'SELECT * FROM tt_content RIGHT JOIN pages pages ON (pages.uid = tt_content.pid) AND ((tt_content.deleted = 0) AND (tt_content.hidden = 0)) WHERE (uid = 1) AND ((pages.deleted = 0) AND (pages.hidden = 0))',
Argument::cetera()
)->willReturn($this->prophesize(Result::class)->reveal());
} else {
$this->connection->executeQuery(
'SELECT * FROM tt_content RIGHT JOIN pages pages ON (pages.uid = tt_content.pid) AND ((tt_content.deleted = 0) AND (tt_content.hidden = 0)) WHERE (uid = 1) AND ((pages.deleted = 0) AND (pages.hidden = 0))',
Argument::cetera()
)->shouldBeCalled();
}

$subject->execute();
}
Expand Down
2 changes: 1 addition & 1 deletion typo3/sysext/core/composer.json
Expand Up @@ -28,7 +28,7 @@
"ext-xml": "*",
"cogpowered/finediff": "~0.3.1",
"doctrine/annotations": "^1.7",
"doctrine/dbal": "~2.10.0 || ~2.11.2",
"doctrine/dbal": "~2.10.0 || ~2.11.2 || ~2.13.1",
"doctrine/instantiator": "^1.1",
"doctrine/lexer": "^1.0",
"egulias/email-validator": "^2.1",
Expand Down
109 changes: 95 additions & 14 deletions typo3/sysext/extbase/Tests/Functional/Service/ExtensionServiceTest.php
Expand Up @@ -20,6 +20,7 @@
use Prophecy\Argument;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
use TYPO3\CMS\Extbase\Configuration\FrontendConfigurationManager;
use TYPO3\CMS\Extbase\Exception;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
use TYPO3\CMS\Extbase\Service\EnvironmentService;
use TYPO3\CMS\Extbase\Service\ExtensionService;
Expand All @@ -37,32 +38,112 @@ class ExtensionServiceTest extends FunctionalTestCase
*/
protected $coreExtensionsToLoad = ['extbase', 'fluid'];

/**
* @var ExtensionService
*/
protected $extensionService;

/**
* @var \Prophecy\Prophecy\ObjectProphecy|FrontendConfigurationManager
*/
protected $frontendConfigurationManager;

/**
* @var \Prophecy\Prophecy\ObjectProphecy|ObjectManagerInterface
*/
protected $objectManager;

/**
* @var \Prophecy\Prophecy\ObjectProphecy|EnvironmentService
*/
protected $environmentService;

protected function setUp(): void
{
parent::setUp();

$this->environmentService = $this->prophesize(EnvironmentService::class);
$this->environmentService->isEnvironmentInFrontendMode()->willReturn(true);
$this->environmentService->isEnvironmentInBackendMode()->willReturn(false);

$this->frontendConfigurationManager = $this->prophesize(FrontendConfigurationManager::class);

$this->objectManager = $this->prophesize(ObjectManagerInterface::class);

$this->extensionService = new ExtensionService();
}

/**
* @test
*/
public function getPluginNameByActionDetectsPluginNameFromGlobalExtensionConfigurationArray()
{
$environmentService = $this->prophesize(EnvironmentService::class);
$environmentService->isEnvironmentInFrontendMode()->willReturn(true);
$environmentService->isEnvironmentInBackendMode()->willReturn(false);
$environmentService = $environmentService->reveal();
$this->frontendConfigurationManager->getConfiguration(Argument::cetera())->willReturn([]);
$this->objectManager->get(Argument::any())->willReturn($this->frontendConfigurationManager->reveal());
$configurationManager = new ConfigurationManager(
$this->objectManager->reveal(),
$this->environmentService->reveal()
);
$this->extensionService->injectConfigurationManager($configurationManager);

$frontendConfigurationManager = $this->prophesize(FrontendConfigurationManager::class);
$frontendConfigurationManager->getConfiguration(Argument::cetera())->willReturn([]);
$pluginName = $this->extensionService->getPluginNameByAction('BlogExample', 'Blog', 'testForm');

$objectManager = $this->prophesize(ObjectManagerInterface::class);
$objectManager->get(Argument::exact(FrontendConfigurationManager::class))->willReturn($frontendConfigurationManager->reveal());
self::assertSame('Blogs', $pluginName);
}

/**
* @test
*/
public function getTargetPidByPluginSignatureDeterminesTheTargetPidIfDefaultPidIsAuto()
{
$this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Service/Fixtures/tt_content_with_single_plugin.xml');

$this->frontendConfigurationManager->getConfiguration(Argument::cetera())->willReturn(['view' => ['defaultPid' => 'auto']]);
$this->objectManager->get(Argument::any())->willReturn($this->frontendConfigurationManager->reveal());
$configurationManager = new ConfigurationManager(
$this->objectManager->reveal(),
$this->environmentService->reveal()
);
$this->extensionService->injectConfigurationManager($configurationManager);

$expectedResult = 321;
$result = $this->extensionService->getTargetPidByPlugin('ExtensionName', 'SomePlugin');
self::assertEquals($expectedResult, $result);
}

/**
* @test
*/
public function getTargetPidByPluginSignatureReturnsNullIfTargetPidCouldNotBeDetermined()
{
$this->frontendConfigurationManager->getConfiguration(Argument::cetera())->willReturn(['view' => ['defaultPid' => 'auto']]);
$this->objectManager->get(Argument::any())->willReturn($this->frontendConfigurationManager->reveal());
$configurationManager = new ConfigurationManager(
$objectManager->reveal(),
$environmentService
$this->objectManager->reveal(),
$this->environmentService->reveal()
);
$this->extensionService->injectConfigurationManager($configurationManager);

$extensionService = new ExtensionService();
$extensionService->injectConfigurationManager($configurationManager);
$result = $this->extensionService->getTargetPidByPlugin('ExtensionName', 'SomePlugin');
self::assertNull($result);
}

$pluginName = $extensionService->getPluginNameByAction('BlogExample', 'Blog', 'testForm');
/**
* @test
*/
public function getTargetPidByPluginSignatureThrowsExceptionIfMoreThanOneTargetPidsWereFound()
{
$this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Service/Fixtures/tt_content_with_two_plugins.xml');
$this->frontendConfigurationManager->getConfiguration(Argument::cetera())->willReturn(['view' => ['defaultPid' => 'auto']]);
$this->objectManager->get(Argument::any())->willReturn($this->frontendConfigurationManager->reveal());
$configurationManager = new ConfigurationManager(
$this->objectManager->reveal(),
$this->environmentService->reveal()
);
$this->extensionService->injectConfigurationManager($configurationManager);

self::assertSame('Blogs', $pluginName);
$this->expectException(Exception::class);
$this->expectExceptionCode(1280773643);
$this->extensionService->getTargetPidByPlugin('ExtensionName', 'SomePlugin');
}
}
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<dataset>
<tt_content>
<uid>4711</uid>
<pid>321</pid>
<CType>list</CType>
<list_type>extensionname_someplugin</list_type>
<sys_language_uid>0</sys_language_uid>
</tt_content>
</dataset>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<dataset>
<tt_content>
<uid>4711</uid>
<pid>321</pid>
<CType>list</CType>
<list_type>extensionname_someplugin</list_type>
<sys_language_uid>0</sys_language_uid>
</tt_content>
<tt_content>
<uid>4712</uid>
<pid>322</pid>
<CType>list</CType>
<list_type>extensionname_someplugin</list_type>
<sys_language_uid>0</sys_language_uid>
</tt_content>
</dataset>

0 comments on commit 76c5d9d

Please sign in to comment.