From 1b615cdffc60489671ec4dccffae224ef02c5c51 Mon Sep 17 00:00:00 2001 From: Sven Baumann Date: Fri, 9 Apr 2021 12:22:47 +0200 Subject: [PATCH 1/6] Added the missing picker configuration --- src/Controller/BackendTreeController.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Controller/BackendTreeController.php b/src/Controller/BackendTreeController.php index 0a49a1bf0..a71388791 100644 --- a/src/Controller/BackendTreeController.php +++ b/src/Controller/BackendTreeController.php @@ -3,7 +3,7 @@ /** * This file is part of contao-community-alliance/dc-general. * - * (c) 2013-2019 Contao Community Alliance. + * (c) 2013-2021 Contao Community Alliance. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -13,7 +13,7 @@ * @package contao-community-alliance/dc-general * @author Christian Schiffler * @author Sven Baumann - * @copyright 2013-2019 Contao Community Alliance. + * @copyright 2013-2021 Contao Community Alliance. * @license https://github.com/contao-community-alliance/dc-general/blob/master/LICENSE LGPL-3.0-or-later * @filesource */ @@ -354,7 +354,8 @@ private function prepareTreeSelector(PickerInterface $picker) if (!isset($information['eval'])) { $information['eval'] = array(); } - $information['eval'] = array_merge($property->getExtra(), $information['eval']); + $information['eval'] = + array_merge($property->getExtra(), $information['eval'], $picker->getConfig()->getExtras()); $treeSelector = new $GLOBALS['BE_FFL']['DcGeneralTreePicker']( Widget::getAttributesFromDca( From 4ab9594124eac219cf0f5944b0476f7ec85133e8 Mon Sep 17 00:00:00 2001 From: Sven Baumann Date: Fri, 9 Apr 2021 12:25:54 +0200 Subject: [PATCH 2/6] The configuration of the sorting is not only related to the request parameters --- src/Contao/View/Contao2BackendView/TreePicker.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Contao/View/Contao2BackendView/TreePicker.php b/src/Contao/View/Contao2BackendView/TreePicker.php index e4c17d100..cfbc5586d 100644 --- a/src/Contao/View/Contao2BackendView/TreePicker.php +++ b/src/Contao/View/Contao2BackendView/TreePicker.php @@ -1096,6 +1096,8 @@ private function pushRootModelToTreeCollection( $sortDirection = $inputProvider->getParameter('sortDirection'); $baseConfig->setSorting([$orderProperty => $sortDirection]); + } elseif ($this->orderProperty && $this->sortDirection) { + $baseConfig->setSorting([$this->orderProperty => $this->sortDirection]); } // Fetch all root elements. From bd2dbf87970d810f1592f4cbecb35b59fc329993 Mon Sep 17 00:00:00 2001 From: Sven Baumann Date: Fri, 9 Apr 2021 12:46:46 +0200 Subject: [PATCH 3/6] Move the config registry in the new config namespace --- .ide-config/renamed.php | 74 +++++ src/{ => Config}/BaseConfigRegistry.php | 9 +- .../BaseConfigRegistryInterface.php | 7 +- src/deprecated-autoload.php | 35 ++- tests/BaseConfigRegistryTest.php | 6 +- tests/Config/BaseConfigRegistryTest.php | 272 ++++++++++++++++++ tests/Contao/Event/SubscriberTest.php | 6 +- tests/DeprecatedAutoloaderTest.php | 135 +++++++++ 8 files changed, 523 insertions(+), 21 deletions(-) create mode 100644 .ide-config/renamed.php rename src/{ => Config}/BaseConfigRegistry.php (95%) rename src/{ => Config}/BaseConfigRegistryInterface.php (85%) create mode 100644 tests/Config/BaseConfigRegistryTest.php create mode 100644 tests/DeprecatedAutoloaderTest.php diff --git a/.ide-config/renamed.php b/.ide-config/renamed.php new file mode 100644 index 000000000..2875f1863 --- /dev/null +++ b/.ide-config/renamed.php @@ -0,0 +1,74 @@ + + * @copyright 2013-2021 Contao Community Alliance. + * @license https://github.com/contao-community-alliance/dc-general/blob/master/LICENSE LGPL-3.0-or-later + * @filesource + */ + +// This file is only here to allow IDE auto-completion. +// @codingStandardsIgnoreFile + +namespace ContaoCommunityAlliance\DcGeneral { + + /** + * @deprecated This class renamed, use + * @see \ContaoCommunityAlliance\DcGeneral\Config\BaseConfigRegistry + */ + class BaseConfigRegistry extends \ContaoCommunityAlliance\DcGeneral\Config\BaseConfigRegistry {} + + /** + * @deprecated This interface renamed, use + * @see \ContaoCommunityAlliance\DcGeneral\Config\BaseConfigRegistryInterface + */ + interface BaseConfigRegistryInterface extends \ContaoCommunityAlliance\DcGeneral\Config\BaseConfigRegistryInterface {} +} + +namespace ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception { + if (false) { + /** + * @deprecated This class is renamed, use + * @see \ContaoCommunityAlliance\DcGeneral\Exception\DefinitionException + */ + class DefinitionException extends \ContaoCommunityAlliance\DcGeneral\Exception\DefinitionException {} + + /** + * @deprecated This class is renamed, use + * @see \ContaoCommunityAlliance\DcGeneral\Exception\EditOnlyModeException + */ + class EditOnlyModeException extends \ContaoCommunityAlliance\DcGeneral\Exception\EditOnlyModeException {} + + /** + * @deprecated This class is renamed, use + * @see \ContaoCommunityAlliance\DcGeneral\Exception\NotCreatableException + */ + class NotCreatableException extends \ContaoCommunityAlliance\DcGeneral\Exception\NotCreatableException {} + + /** + * @deprecated This class is renamed, use + * @see \ContaoCommunityAlliance\DcGeneral\Exception\NotDeletableException + */ + class NotDeletableException extends \ContaoCommunityAlliance\DcGeneral\Exception\NotDeletableException {} + } +} + +namespace ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Subscriber { + if (false) { + /** + * @deprecated This class is renamed, use + * @see \ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\EventListener\ColorPickerWizardListener + */ + class ColorPickerWizardSubscriber extends \ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\EventListener\ColorPickerWizardListener {} + } +} diff --git a/src/BaseConfigRegistry.php b/src/Config/BaseConfigRegistry.php similarity index 95% rename from src/BaseConfigRegistry.php rename to src/Config/BaseConfigRegistry.php index d9631a032..03b130a9b 100644 --- a/src/BaseConfigRegistry.php +++ b/src/Config/BaseConfigRegistry.php @@ -3,7 +3,7 @@ /** * This file is part of contao-community-alliance/dc-general. * - * (c) 2013-2019 Contao Community Alliance. + * (c) 2013-2021 Contao Community Alliance. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -13,24 +13,25 @@ * @package contao-community-alliance/dc-general * @author Christian Schiffler * @author Sven Baumann - * @copyright 2013-2019 Contao Community Alliance. + * @copyright 2013-2021 Contao Community Alliance. * @license https://github.com/contao-community-alliance/dc-general/blob/master/LICENSE LGPL-3.0-or-later * @filesource */ -namespace ContaoCommunityAlliance\DcGeneral; +namespace ContaoCommunityAlliance\DcGeneral\Config; use ContaoCommunityAlliance\DcGeneral\Contao\DataDefinition\Definition\Contao2BackendViewDefinitionInterface; use ContaoCommunityAlliance\DcGeneral\Data\ConfigInterface; use ContaoCommunityAlliance\DcGeneral\Data\ModelId; use ContaoCommunityAlliance\DcGeneral\Data\ModelIdInterface; use ContaoCommunityAlliance\DcGeneral\DataDefinition\Definition\BasicDefinitionInterface; +use ContaoCommunityAlliance\DcGeneral\EnvironmentInterface; use ContaoCommunityAlliance\DcGeneral\Exception\DcGeneralRuntimeException; /** * Registry for default data provider configurations to only resolve them once. */ -class BaseConfigRegistry implements BaseConfigRegistryInterface +final class BaseConfigRegistry implements BaseConfigRegistryInterface { /** * The attached environment. diff --git a/src/BaseConfigRegistryInterface.php b/src/Config/BaseConfigRegistryInterface.php similarity index 85% rename from src/BaseConfigRegistryInterface.php rename to src/Config/BaseConfigRegistryInterface.php index 94817b74e..ac0b80138 100644 --- a/src/BaseConfigRegistryInterface.php +++ b/src/Config/BaseConfigRegistryInterface.php @@ -3,7 +3,7 @@ /** * This file is part of contao-community-alliance/dc-general. * - * (c) 2013-2019 Contao Community Alliance. + * (c) 2013-2021 Contao Community Alliance. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -13,15 +13,16 @@ * @package contao-community-alliance/dc-general * @author Christian Schiffler * @author Sven Baumann - * @copyright 2013-2019 Contao Community Alliance. + * @copyright 2013-2021 Contao Community Alliance. * @license https://github.com/contao-community-alliance/dc-general/blob/master/LICENSE LGPL-3.0-or-later * @filesource */ -namespace ContaoCommunityAlliance\DcGeneral; +namespace ContaoCommunityAlliance\DcGeneral\Config; use ContaoCommunityAlliance\DcGeneral\Data\ConfigInterface; use ContaoCommunityAlliance\DcGeneral\Data\ModelIdInterface; +use ContaoCommunityAlliance\DcGeneral\EnvironmentAwareInterface; /** * Registry for default data provider configurations to only resolve them once. diff --git a/src/deprecated-autoload.php b/src/deprecated-autoload.php index 32a9f7c78..3f594713a 100644 --- a/src/deprecated-autoload.php +++ b/src/deprecated-autoload.php @@ -3,7 +3,7 @@ /** * This file is part of contao-community-alliance/dc-general. * - * (c) 2013-2019 Contao Community Alliance. + * (c) 2013-2021 Contao Community Alliance. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -13,12 +13,14 @@ * @package contao-community-alliance/dc-general * @author Sven Baumann * @author Richard Henkenjohann - * @copyright 2013-2019 Contao Community Alliance. + * @copyright 2013-2021 Contao Community Alliance. * @license https://github.com/contao-community-alliance/dc-general/blob/master/LICENSE LGPL-3.0-or-later * @filesource */ // This hack is to load the "old locations" of the classes. +use ContaoCommunityAlliance\DcGeneral\Config\BaseConfigRegistry; +use ContaoCommunityAlliance\DcGeneral\Config\BaseConfigRegistryInterface; use ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\EventListener\ColorPickerWizardListener; use ContaoCommunityAlliance\DcGeneral\Exception\DefinitionException; use ContaoCommunityAlliance\DcGeneral\Exception\EditOnlyModeException; @@ -28,14 +30,15 @@ spl_autoload_register( function ($class) { static $classes = [ - '\ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception\DefinitionException' => DefinitionException::class, - '\ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception\EditOnlyModeException' => EditOnlyModeException::class, - '\ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception\NotCreatableException' => NotCreatableException::class, - '\ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception\NotDeletableException' => NotDeletableException::class, - '\ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Subscriber\ColorPickerWizardSubscriber' => ColorPickerWizardListener::class, + 'ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception\DefinitionException' => DefinitionException::class, + 'ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception\EditOnlyModeException' => EditOnlyModeException::class, + 'ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception\NotCreatableException' => NotCreatableException::class, + 'ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception\NotDeletableException' => NotDeletableException::class, + 'ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Subscriber\ColorPickerWizardSubscriber' => ColorPickerWizardListener::class, + 'ContaoCommunityAlliance\DcGeneral\BaseConfigRegistry' => BaseConfigRegistry::class, ]; - if (isset($classes[$class])) { + if (isset($classes[($class)])) { // @codingStandardsIgnoreStart Silencing errors is discouraged @trigger_error('Class "' . $class . '" has been renamed to "' . $classes[$class] . '"', E_USER_DEPRECATED); // @codingStandardsIgnoreEnd @@ -46,5 +49,21 @@ function ($class) { class_alias($classes[$class], $class); } + + static $interfaces = [ + 'ContaoCommunityAlliance\DcGeneral\BaseConfigRegistryInterface' => BaseConfigRegistryInterface::class + ]; + + if (isset($interfaces[($class)])) { + // @codingStandardsIgnoreStart Silencing errors is discouraged + @trigger_error('Interface "' . $class . '" has been renamed to "' . $interfaces[$class] . '"', E_USER_DEPRECATED); + // @codingStandardsIgnoreEnd + + if (!interface_exists($interfaces[$class])) { + spl_autoload_call($class); + } + + class_alias($interfaces[$class], $class); + } } ); diff --git a/tests/BaseConfigRegistryTest.php b/tests/BaseConfigRegistryTest.php index 272da9607..e9ef363f8 100644 --- a/tests/BaseConfigRegistryTest.php +++ b/tests/BaseConfigRegistryTest.php @@ -3,7 +3,7 @@ /** * This file is part of contao-community-alliance/dc-general. * - * (c) 2013-2019 Contao Community Alliance. + * (c) 2013-2021 Contao Community Alliance. * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,7 +12,7 @@ * * @package contao-community-alliance/dc-general * @author Sven Baumann - * @copyright 2013-2019 Contao Community Alliance. + * @copyright 2013-2021 Contao Community Alliance. * @license https://github.com/contao-community-alliance/dc-general/blob/master/LICENSE LGPL-3.0-or-later * @filesource */ @@ -43,6 +43,8 @@ * Test the base configuration registry. * * @covers \ContaoCommunityAlliance\DcGeneral\BaseConfigRegistry + * + * @deprecated Is deprecated since DcGeneral 2.2.0 and where removed in DcGeneral 3.0. */ class BaseConfigRegistryTest extends TestCase { diff --git a/tests/Config/BaseConfigRegistryTest.php b/tests/Config/BaseConfigRegistryTest.php new file mode 100644 index 000000000..b9427032f --- /dev/null +++ b/tests/Config/BaseConfigRegistryTest.php @@ -0,0 +1,272 @@ + + * @copyright 2013-2021 Contao Community Alliance. + * @license https://github.com/contao-community-alliance/dc-general/blob/master/LICENSE LGPL-3.0-or-later + * @filesource + */ + +namespace ContaoCommunityAlliance\DcGeneral\Test\Config; + +use ContaoCommunityAlliance\DcGeneral\Config\BaseConfigRegistry; +use ContaoCommunityAlliance\DcGeneral\Config\BaseConfigRegistryInterface; +use ContaoCommunityAlliance\DcGeneral\Contao\DataDefinition\Definition\Contao2BackendViewDefinitionInterface; +use ContaoCommunityAlliance\DcGeneral\Data\ConfigInterface; +use ContaoCommunityAlliance\DcGeneral\Data\DefaultConfig; +use ContaoCommunityAlliance\DcGeneral\Data\DefaultDataProvider; +use ContaoCommunityAlliance\DcGeneral\Data\DefaultModel; +use ContaoCommunityAlliance\DcGeneral\Data\ModelId; +use ContaoCommunityAlliance\DcGeneral\DataDefinition\DefaultContainer; +use ContaoCommunityAlliance\DcGeneral\DataDefinition\Definition\BasicDefinitionInterface; +use ContaoCommunityAlliance\DcGeneral\DataDefinition\Definition\DefaultBasicDefinition; +use ContaoCommunityAlliance\DcGeneral\DataDefinition\Definition\ModelRelationshipDefinitionInterface; +use ContaoCommunityAlliance\DcGeneral\DataDefinition\Definition\View\ListingConfigInterface; +use ContaoCommunityAlliance\DcGeneral\DataDefinition\ModelRelationship\ParentChildConditionInterface; +use ContaoCommunityAlliance\DcGeneral\DefaultEnvironment; +use ContaoCommunityAlliance\DcGeneral\EnvironmentInterface; +use ContaoCommunityAlliance\DcGeneral\Exception\DcGeneralRuntimeException; +use ContaoCommunityAlliance\DcGeneral\InputProviderInterface; +use PHPUnit\Framework\TestCase; + +/** + * Test the base configuration registry. + * + * @covers \ContaoCommunityAlliance\DcGeneral\Config\BaseConfigRegistry + */ +class BaseConfigRegistryTest extends TestCase +{ + public function testSetterAndGetter() + { + $environment = $this->getMockBuilder(EnvironmentInterface::class)->getMock(); + + $configRegistry = new BaseConfigRegistry(); + + self::assertNull($configRegistry->getEnvironment()); + + self::assertInstanceOf(BaseConfigRegistryInterface::class, $configRegistry->setEnvironment($environment)); + self::assertInstanceOf(EnvironmentInterface::class, $configRegistry->getEnvironment()); + self::assertSame($environment, $configRegistry->getEnvironment()); + } + + public function testGetBaseConfig() + { + // Common test settings. + $basicDefinition = + $this->getMockBuilder(DefaultBasicDefinition::class)->enableProxyingToOriginalMethods()->getMock(); + $dataDefinition = + $this->getMockBuilder(DefaultContainer::class)->disableOriginalConstructor()->getMock(); + $environment = + $this->getMockBuilder(DefaultEnvironment::class)->setMethods(['getDataDefinition'])->getMock(); + $viewDefinition = $this->createMock(Contao2BackendViewDefinitionInterface::class); + $listingConfig = $this->getMockBuilder(ListingConfigInterface::class)->getMock(); + $modelRelationShip = $this->createMock(ModelRelationshipDefinitionInterface::class); + $parentChildCondition = $this->createMock(ParentChildConditionInterface::class); + + $viewDefinition->method('getListingConfig')->willReturn($listingConfig); + + $definition = [ + Contao2BackendViewDefinitionInterface::NAME => $viewDefinition + ]; + $dataDefinition->method('hasDefinition')->will( + self::returnCallback( + function ($definitionName) use ($definition) { + return array_key_exists($definitionName, $definition); + } + ) + ); + $dataDefinition->method('getDefinition')->will( + self::returnCallback( + function ($definitionName) use ($definition) { + return $definition[$definitionName]; + } + ) + ); + $dataDefinition->method('getModelRelationshipDefinition')->willReturn($modelRelationShip); + + $parentChildFilter = ['child' => 'bar']; + $parentChildCondition->method('getFilter')->willReturn($parentChildFilter); + + $modelRelationShip->method('getChildCondition')->will( + self::returnCallback( + function ($parentProviderName) use ($parentChildCondition) { + if ('parentIdWithCondition' === $parentProviderName) { + return $parentChildCondition; + } + + return null; + } + ) + ); + + $environment->method('getDataDefinition')->willReturn($dataDefinition); + + $configRegistry = new BaseConfigRegistry(); + $configRegistry->setEnvironment($environment); + + // Single data provider test settings. + $dataDefinition->method('getBasicDefinition')->willReturn($basicDefinition); + $singleDataProvider = $this->createMock(DefaultDataProvider::class); + $singleDataProviderConfig = DefaultConfig::init(); + $singleDataProvider->method('getEmptyConfig')->willReturn($singleDataProviderConfig); + $singleAdditionalFilter = ['single' => 'foo']; + $singleAdditionalFilter2 = ['single' => 'bar']; + + // Single data provider tests. + $environment->addDataProvider('single', $singleDataProvider); + $basicDefinition->setDataProvider('single'); + $basicDefinition->setAdditionalFilter('single', $singleAdditionalFilter); + self::assertInstanceOf(ConfigInterface::class, $configRegistry->getBaseConfig(null)); + self::assertIsArray($singleDataProviderConfig->getFilter()); + self::assertSame($singleAdditionalFilter, $singleDataProviderConfig->getFilter()); + // Test get single data provider from cache. + $basicDefinition->setAdditionalFilter('single', $singleAdditionalFilter2); + self::assertInstanceOf(ConfigInterface::class, $configRegistry->getBaseConfig(null)); + self::assertIsArray($singleDataProviderConfig->getFilter()); + self::assertNotSame($singleAdditionalFilter2, $singleDataProviderConfig->getFilter()); + + // ParentId data provider test settings. + $parentIdDataProvider = $this->createMock(DefaultDataProvider::class); + $parentIdDataProviderConfig = DefaultConfig::init(); + $parentIdDataProvider->method('getEmptyConfig')->willReturn($parentIdDataProviderConfig); + + // ParentId data provider test exception unexpected parent provider. + $unexpectedModelId = ModelId::fromValues('parentId', 'unexpected-parent-provider'); + $environment->addDataProvider('parentId', $parentIdDataProvider); + $basicDefinition->setParentDataProvider('unexpectedDataProvider'); + try { + $configRegistry->getBaseConfig($unexpectedModelId); + } catch (\Exception $exception) { + self::assertInstanceOf(DcGeneralRuntimeException::class, $exception); + self::assertSame( + 'Unexpected parent provider parentId (expected unexpectedDataProvider)', + $exception->getMessage() + ); + } + + // ParentId data provider test exception parent item not found. + $itemNotFoundModelId = ModelId::fromValues('parentId', 'item-not-found'); + $basicDefinition->setParentDataProvider('parentId'); + try { + $configRegistry->getBaseConfig($itemNotFoundModelId); + } catch (\Exception $exception) { + self::assertInstanceOf(DcGeneralRuntimeException::class, $exception); + self::assertSame( + 'Parent item parentId::Iml0ZW0tbm90LWZvdW5kIg== not found in parentId', + $exception->getMessage() + ); + } + + // ParentId data provider tests. + $modelId = ModelId::fromValues('parentId', 'id-parent'); + $parentIdModel = $this->createMock(DefaultModel::class); + $parentIdAdditionalFilter = ['parentId' => 'foo']; + $parentIdDataProvider->method('fetch')->willReturn($parentIdModel); + $basicDefinition->setAdditionalFilter('single', $singleAdditionalFilter); + $basicDefinition->setAdditionalFilter('parentId', $parentIdAdditionalFilter); + self::assertInstanceOf(ConfigInterface::class, $configRegistry->getBaseConfig($modelId)); + self::assertIsArray($singleDataProviderConfig->getFilter()); + self::assertSame($singleAdditionalFilter, $singleDataProviderConfig->getFilter()); + + // ParentId data provider tests with child condition. + $modelIdWithChildCondition = ModelId::fromValues('parentIdWithCondition', 'id-parent-with-child-condition'); + $environment->addDataProvider('parentIdWithCondition', $parentIdDataProvider); + $basicDefinition->setParentDataProvider('parentIdWithCondition'); + $exceptedFilterWithChildCondition = [ + [ + 'operation' => 'AND', + 'children' => array_merge($singleAdditionalFilter, $parentChildFilter) + ] + ]; + self::assertInstanceOf(ConfigInterface::class, $configRegistry->getBaseConfig($modelIdWithChildCondition)); + self::assertIsArray($singleDataProviderConfig->getFilter()); + self::assertSame($exceptedFilterWithChildCondition, $singleDataProviderConfig->getFilter()); + } + + public function testGetBaseConfigParentListMode() + { + $basicDefinition = + $this->getMockBuilder(DefaultBasicDefinition::class)->enableProxyingToOriginalMethods()->getMock(); + $dataDefinition = + $this->getMockBuilder(DefaultContainer::class)->disableOriginalConstructor()->getMock(); + $environment = + $this + ->getMockBuilder(DefaultEnvironment::class) + ->setMethods( + [ + 'getDataDefinition', + 'getInputProvider' + ] + ) + ->getMock(); + $viewDefinition = $this->createMock(Contao2BackendViewDefinitionInterface::class); + $listingConfig = $this->getMockBuilder(ListingConfigInterface::class)->getMock(); + $dataProvider = $this->createMock(DefaultDataProvider::class); + $modelRelationShip = $this->createMock(ModelRelationshipDefinitionInterface::class); + $parentDataProvider = $this->createMock(DefaultDataProvider::class); + + $dataProviderConfig = DefaultConfig::init(); + $dataProvider->method('getEmptyConfig')->willReturn($dataProviderConfig); + + $viewDefinition->method('getListingConfig')->willReturn($listingConfig); + + $modelRelationShip->method('getChildCondition')->willReturn(null); + + $dataDefinition->method('getModelRelationshipDefinition')->willReturn($modelRelationShip); + $definition = [ + Contao2BackendViewDefinitionInterface::NAME => $viewDefinition + ]; + $dataDefinition->method('hasDefinition')->will( + self::returnCallback( + function ($definitionName) use ($definition) { + return array_key_exists($definitionName, $definition); + } + ) + ); + $dataDefinition->method('getDefinition')->will( + self::returnCallback( + function ($definitionName) use ($definition) { + return $definition[$definitionName]; + } + ) + ); + + $inputProvider = $this->createMock(InputProviderInterface::class); + + $environment->method('getDataDefinition')->willReturn($dataDefinition); + $environment->method('getInputProvider')->willReturn($inputProvider); + + $dataDefinition->method('getBasicDefinition')->willReturn($basicDefinition); + + $parentModel = $this->createMock(DefaultModel::class); + $parentDataProvider->method('fetch')->willReturn($parentModel); + $parentDataProviderConfig = DefaultConfig::init(); + $parentDataProvider->method('getEmptyConfig')->willReturn($parentDataProviderConfig); + + $configRegistry = new BaseConfigRegistry(); + $configRegistry->setEnvironment($environment); + + $parentListModelId = ModelId::fromValues('parent-list', 'id-parent'); + $inputProvider->method('getParameter')->willReturn($parentListModelId->getSerialized()); + $environment->addDataProvider('current', $dataProvider); + $environment->addDataProvider('parent-list', $parentDataProvider); + $basicDefinition->setDataProvider('current'); + $basicDefinition->setParentDataProvider('parent-list'); + $basicDefinition->setMode(BasicDefinitionInterface::MODE_PARENTEDLIST); + $additionalFilter = ['current' => 'foo']; + $basicDefinition->setAdditionalFilter('current', $additionalFilter); + self::assertInstanceOf(ConfigInterface::class, $configRegistry->getBaseConfig(null)); + self::assertIsArray($dataProviderConfig->getFilter()); + self::assertSame($additionalFilter, $dataProviderConfig->getFilter()); + } +} diff --git a/tests/Contao/Event/SubscriberTest.php b/tests/Contao/Event/SubscriberTest.php index 56bf47953..fa18db6b3 100644 --- a/tests/Contao/Event/SubscriberTest.php +++ b/tests/Contao/Event/SubscriberTest.php @@ -24,7 +24,7 @@ use ContaoCommunityAlliance\Contao\Bindings\ContaoEvents; use ContaoCommunityAlliance\Contao\Bindings\Events\Date\ParseDateEvent; use ContaoCommunityAlliance\DcGeneral\Action; -use ContaoCommunityAlliance\DcGeneral\BaseConfigRegistry; +use ContaoCommunityAlliance\DcGeneral\BaseConfigRegistryInterface; use ContaoCommunityAlliance\DcGeneral\Contao\DataDefinition\Definition\Contao2BackendViewDefinition; use ContaoCommunityAlliance\DcGeneral\Contao\DataDefinition\Definition\Contao2BackendViewDefinitionInterface; use ContaoCommunityAlliance\DcGeneral\Contao\Event\Subscriber; @@ -551,9 +551,7 @@ public function testInitializePanels($actionName, $viewClass, $constructor, $exc $environment->setDataDefinition($dataDefinition); $baseConfigRegistry = $this - ->getMockBuilder(BaseConfigRegistry::class) - ->setMethods(['getBaseConfig']) - ->getMock(); + ->getMockForAbstractClass(BaseConfigRegistryInterface::class); $environment->setBaseConfigRegistry($baseConfigRegistry); $dataConfig = DefaultConfig::init(); diff --git a/tests/DeprecatedAutoloaderTest.php b/tests/DeprecatedAutoloaderTest.php new file mode 100644 index 000000000..e4ea6447f --- /dev/null +++ b/tests/DeprecatedAutoloaderTest.php @@ -0,0 +1,135 @@ + + * @copyright 2013-2021 Contao Community Alliance. + * @license https://github.com/contao-community-alliance/dc-general/blob/master/LICENSE LGPL-3.0-or-later + * @filesource + */ + +declare(strict_types=1); + +namespace ContaoCommunityAlliance\DcGeneral\Test; + +use ContaoCommunityAlliance\DcGeneral\Config\BaseConfigRegistry; +use ContaoCommunityAlliance\DcGeneral\Config\BaseConfigRegistryInterface; +use ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\EventListener\ColorPickerWizardListener; +use ContaoCommunityAlliance\DcGeneral\Exception\DefinitionException; +use ContaoCommunityAlliance\DcGeneral\Exception\EditOnlyModeException; +use ContaoCommunityAlliance\DcGeneral\Exception\NotCreatableException; +use ContaoCommunityAlliance\DcGeneral\Exception\NotDeletableException; +use PHPUnit\Framework\TestCase; + +/** + * This class tests if the deprecated autoloader works. + * + * @covers \ContaoCommunityAlliance\DcGeneral\Exception\DefinitionException + * @covers \ContaoCommunityAlliance\DcGeneral\Exception\EditOnlyModeException + * @covers \ContaoCommunityAlliance\DcGeneral\Exception\NotCreatableException + * @covers \ContaoCommunityAlliance\DcGeneral\Exception\NotDeletableException + * @covers \ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\EventListener\ColorPickerWizardListener + * @covers \ContaoCommunityAlliance\DcGeneral\Config\BaseConfigRegistryInterface + * @covers \ContaoCommunityAlliance\DcGeneral\Config\BaseConfigRegistry + */ +class DeprecatedAutoloaderTest extends TestCase +{ + /** + * Provide the alias class map. + * + * @return \Generator + */ + public function provideAliasClassMap(): \Generator + { + yield 'ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception\DefinitionException' => [ + 'ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception\DefinitionException', + DefinitionException::class + ]; + + yield 'ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception\EditOnlyModeException' => [ + 'ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception\EditOnlyModeException', + EditOnlyModeException::class + ]; + + yield 'ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception\NotCreatableException' => [ + 'ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception\NotCreatableException', + NotCreatableException::class + ]; + + yield 'ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception\NotDeletableException' => [ + 'ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Exception\NotDeletableException', + NotDeletableException::class + ]; + + yield 'ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Subscriber\ColorPickerWizardSubscriber' => [ + 'ContaoCommunityAlliance\DcGeneral\Contao\View\Contao2BackendView\Subscriber\ColorPickerWizardSubscriber', + ColorPickerWizardListener::class + ]; + + yield 'ContaoCommunityAlliance\DcGeneral\BaseConfigRegistry' => [ + 'ContaoCommunityAlliance\DcGeneral\BaseConfigRegistry', + BaseConfigRegistry::class + ]; + } + + /** + * Provide the alias interface map. + * + * @return \Generator + */ + public function provideAliasInterfaceMap(): \Generator + { + yield 'ContaoCommunityAlliance\DcGeneral\BaseConfigRegistryInterface' => [ + 'ContaoCommunityAlliance\DcGeneral\BaseConfigRegistryInterface', + BaseConfigRegistryInterface::class + ]; + } + + /** + * Test if the deprecated classes are aliased to the new one. + * + * @param string $oldClass Old class name. + * @param string $newClass New class name. + * + * @dataProvider provideAliasClassMap + */ + public function testDeprecatedClassesAreAliased(string $oldClass, string $newClass): void + { + self::assertTrue(\class_exists($oldClass), \sprintf('Class select "%s" is not found.', $oldClass)); + + $oldClassReflection = new \ReflectionClass($oldClass); + $newClassReflection = new \ReflectionClass($newClass); + + self::assertSame($newClassReflection->getFileName(), $oldClassReflection->getFileName()); + } + + /** + * Test if the deprecated classes are aliased to the new one. + * + * @param string $oldInterface Old interface name. + * @param string $newInterface New interface name. + * + * @dataProvider provideAliasInterfaceMap + */ + public function testDeprecatedInterfacesAreAliased(string $oldInterface, string $newInterface): void + { + self::assertTrue( + \interface_exists($oldInterface), + \sprintf('Interface select "%s" is not found.', $oldInterface) + ); + + $oldClassReflection = new \ReflectionClass($oldInterface); + $newClassReflection = new \ReflectionClass($newInterface); + + self::assertSame($newClassReflection->getFileName(), $oldClassReflection->getFileName()); + } +} From d57a4e3e9c2f8e7e5102339e4217227f9f488a16 Mon Sep 17 00:00:00 2001 From: Sven Baumann Date: Sat, 10 Apr 2021 15:01:37 +0200 Subject: [PATCH 4/6] Add new config registry flat. The flat config registry is there to map a data definition that has a parent definition as a flat. In this registry, no filtering or similar is applied by the parent. --- src/Config/FlatConfigRegistry.php | 105 ++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 src/Config/FlatConfigRegistry.php diff --git a/src/Config/FlatConfigRegistry.php b/src/Config/FlatConfigRegistry.php new file mode 100644 index 000000000..6d9b54d0c --- /dev/null +++ b/src/Config/FlatConfigRegistry.php @@ -0,0 +1,105 @@ + + * @copyright 2013-2021 Contao Community Alliance. + * @license https://github.com/contao-community-alliance/dc-general/blob/master/LICENSE LGPL-3.0-or-later + * @filesource + */ + +declare(strict_types=1); + +namespace ContaoCommunityAlliance\DcGeneral\Config; + +use ContaoCommunityAlliance\DcGeneral\Contao\DataDefinition\Definition\Contao2BackendViewDefinitionInterface; +use ContaoCommunityAlliance\DcGeneral\Data\ConfigInterface; +use ContaoCommunityAlliance\DcGeneral\Data\ModelIdInterface; +use ContaoCommunityAlliance\DcGeneral\EnvironmentFlatConfigRegistryInterface; +use ContaoCommunityAlliance\DcGeneral\EnvironmentInterface; + +/** + * Registry for default data provider configurations to only resolve them once. + * The flat config registry is there to map a data definition that has a parent definition as a flat. + * In this registry, no filtering or similar is applied by the parent. + */ +final class FlatConfigRegistry implements BaseConfigRegistryInterface +{ + /** + * The attached environment. + * + * @var EnvironmentFlatConfigRegistryInterface|null + */ + private $environment; + + /** + * {@inheritDoc} + */ + public function getBaseConfig(ModelIdInterface $parentId = null): ConfigInterface + { + $environment = $this->getEnvironment(); + $config = $environment->getDataProvider()->getEmptyConfig(); + $definition = $environment->getDataDefinition(); + $additional = $definition->getBasicDefinition()->getAdditionalFilter(); + + // Custom filter common for all modes. + if ($additional) { + $config->setFilter($additional); + } + + $this->addDefaultSorting($config); + + return $config; + } + + /** + * Add the default sorting fields. + * + * @param ConfigInterface $config The data provider config. + * + * @return void + */ + private function addDefaultSorting(ConfigInterface $config): void + { + if (!empty($config->getSorting())) { + return; + } + + $environment = $this->getEnvironment(); + $definition = $environment->getDataDefinition(); + /** @var Contao2BackendViewDefinitionInterface $viewDefinition */ + $viewDefinition = $definition->getDefinition(Contao2BackendViewDefinitionInterface::NAME); + $config->setSorting($viewDefinition->getListingConfig()->getDefaultSortingFields()); + } + + /** + * {@inheritDoc} + */ + public function getEnvironment(): ?EnvironmentFlatConfigRegistryInterface + { + return $this->environment; + } + + /** + * Set the environment. + * + * @param EnvironmentInterface $environment The environment. + * + * @return FlatConfigRegistry + */ + public function setEnvironment(EnvironmentInterface $environment): FlatConfigRegistry + { + $this->environment = $environment; + + return $this; + } +} From 9af17e5e56bd823933fcfd457dda404cd239008f Mon Sep 17 00:00:00 2001 From: Sven Baumann Date: Sat, 10 Apr 2021 15:04:43 +0200 Subject: [PATCH 5/6] Making the new flat config registry available in the environment --- .../Dca/Populator/HardCodedPopulator.php | 13 +++ src/DefaultEnvironment.php | 29 ++++- ...EnvironmentFlatConfigRegistryInterface.php | 48 ++++++++ .../EnvironmentPopulatorInterface.php | 3 +- tests/Config/FlatConfigRegistryTest.php | 103 ++++++++++++++++++ 5 files changed, 194 insertions(+), 2 deletions(-) create mode 100644 src/EnvironmentFlatConfigRegistryInterface.php create mode 100644 tests/Config/FlatConfigRegistryTest.php diff --git a/src/Contao/Dca/Populator/HardCodedPopulator.php b/src/Contao/Dca/Populator/HardCodedPopulator.php index fff23e39a..0846e586f 100644 --- a/src/Contao/Dca/Populator/HardCodedPopulator.php +++ b/src/Contao/Dca/Populator/HardCodedPopulator.php @@ -23,8 +23,10 @@ use ContaoCommunityAlliance\DcGeneral\BaseConfigRegistry; use ContaoCommunityAlliance\DcGeneral\Clipboard\Clipboard; +use ContaoCommunityAlliance\DcGeneral\Config\FlatConfigRegistry; use ContaoCommunityAlliance\DcGeneral\Contao\InputProvider; use ContaoCommunityAlliance\DcGeneral\Controller\DefaultController; +use ContaoCommunityAlliance\DcGeneral\EnvironmentFlatConfigRegistryInterface; use ContaoCommunityAlliance\DcGeneral\EnvironmentInterface; use ContaoCommunityAlliance\DcGeneral\EnvironmentPopulator\AbstractEventDrivenEnvironmentPopulator; @@ -99,6 +101,17 @@ public function populate(EnvironmentInterface $environment) // @codingStandardsIgnoreEnd } + if (($environment instanceof EnvironmentFlatConfigRegistryInterface) + && (!$environment->getFlatConfigRegistry()) + ) { + $flatConfigRegistry = new FlatConfigRegistry(); + $flatConfigRegistry->setEnvironment($environment); + $environment->setFlatConfigRegistry($flatConfigRegistry); + // @codingStandardsIgnoreStart + @\trigger_error('Fallback populator in use - implement a proper populator!', E_USER_DEPRECATED); + // @codingStandardsIgnoreEnd + } + $this->populateController($environment); } } diff --git a/src/DefaultEnvironment.php b/src/DefaultEnvironment.php index d88ade2ed..9a13d2173 100644 --- a/src/DefaultEnvironment.php +++ b/src/DefaultEnvironment.php @@ -22,6 +22,7 @@ namespace ContaoCommunityAlliance\DcGeneral; use ContaoCommunityAlliance\DcGeneral\Clipboard\ClipboardInterface; +use ContaoCommunityAlliance\DcGeneral\Config\BaseConfigRegistryInterface; use ContaoCommunityAlliance\DcGeneral\Controller\ControllerInterface; use ContaoCommunityAlliance\DcGeneral\Data\DataProviderInterface; use ContaoCommunityAlliance\DcGeneral\DataDefinition\ContainerInterface; @@ -33,7 +34,7 @@ /** * Default implementation of an environment. */ -class DefaultEnvironment implements EnvironmentInterface +class DefaultEnvironment implements EnvironmentInterface, EnvironmentFlatConfigRegistryInterface { /** * The controller. @@ -91,6 +92,13 @@ class DefaultEnvironment implements EnvironmentInterface */ protected $baseConfigRegistry; + /** + * The attached flat config registry. + * + * @var BaseConfigRegistryInterface + */ + protected $flatConfigRegistry; + /** * The registered data providers. * @@ -263,6 +271,25 @@ public function getBaseConfigRegistry() return $this->baseConfigRegistry; } + /** + * {@inheritdoc} + */ + public function setFlatConfigRegistry( + BaseConfigRegistryInterface $flatConfigRegistry + ): EnvironmentFlatConfigRegistryInterface { + $this->flatConfigRegistry = $flatConfigRegistry; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getFlatConfigRegistry(): ?BaseConfigRegistryInterface + { + return $this->flatConfigRegistry; + } + /** * {@inheritdoc} */ diff --git a/src/EnvironmentFlatConfigRegistryInterface.php b/src/EnvironmentFlatConfigRegistryInterface.php new file mode 100644 index 000000000..61ee802f2 --- /dev/null +++ b/src/EnvironmentFlatConfigRegistryInterface.php @@ -0,0 +1,48 @@ + + * @copyright 2013-2021 Contao Community Alliance. + * @license https://github.com/contao-community-alliance/dc-general/blob/master/LICENSE LGPL-3.0-or-later + * @filesource + */ + +declare(strict_types=1); + +namespace ContaoCommunityAlliance\DcGeneral; + +use ContaoCommunityAlliance\DcGeneral\Config\BaseConfigRegistryInterface; + +/** + * The environment interface for the flat config registry. + */ +interface EnvironmentFlatConfigRegistryInterface extends EnvironmentInterface +{ + /** + * Set the base config registry to use. + * + * @param BaseConfigRegistryInterface $baseConfigRegistry The input provider to use. + * + * @return EnvironmentFlatConfigRegistryInterface + */ + public function setFlatConfigRegistry( + BaseConfigRegistryInterface $baseConfigRegistry + ): EnvironmentFlatConfigRegistryInterface; + + /** + * Retrieve the base config registry. + * + * @return BaseConfigRegistryInterface + */ + public function getFlatConfigRegistry(): ?BaseConfigRegistryInterface; +} diff --git a/src/EnvironmentPopulator/EnvironmentPopulatorInterface.php b/src/EnvironmentPopulator/EnvironmentPopulatorInterface.php index 5fc90a26f..c5948eefd 100644 --- a/src/EnvironmentPopulator/EnvironmentPopulatorInterface.php +++ b/src/EnvironmentPopulator/EnvironmentPopulatorInterface.php @@ -20,6 +20,7 @@ namespace ContaoCommunityAlliance\DcGeneral\EnvironmentPopulator; +use ContaoCommunityAlliance\DcGeneral\EnvironmentFlatConfigRegistryInterface; use ContaoCommunityAlliance\DcGeneral\EnvironmentInterface; /** @@ -33,7 +34,7 @@ interface EnvironmentPopulatorInterface /** * Create all needed objects the populator knows to create and put them into the environment. * - * @param EnvironmentInterface $environment The environment to populate. + * @param EnvironmentInterface|EnvironmentFlatConfigRegistryInterface $environment The environment to populate. * * @return void */ diff --git a/tests/Config/FlatConfigRegistryTest.php b/tests/Config/FlatConfigRegistryTest.php new file mode 100644 index 000000000..4b95627d3 --- /dev/null +++ b/tests/Config/FlatConfigRegistryTest.php @@ -0,0 +1,103 @@ + + * @copyright 2013-2021 Contao Community Alliance. + * @license https://github.com/contao-community-alliance/dc-general/blob/master/LICENSE LGPL-3.0-or-later + * @filesource + */ + +namespace ContaoCommunityAlliance\DcGeneral\Test\Config; + +use ContaoCommunityAlliance\DcGeneral\Config\BaseConfigRegistryInterface; +use ContaoCommunityAlliance\DcGeneral\Config\FlatConfigRegistry; +use ContaoCommunityAlliance\DcGeneral\Contao\DataDefinition\Definition\Contao2BackendViewDefinitionInterface; +use ContaoCommunityAlliance\DcGeneral\Data\ConfigInterface; +use ContaoCommunityAlliance\DcGeneral\Data\DefaultConfig; +use ContaoCommunityAlliance\DcGeneral\Data\DefaultDataProvider; +use ContaoCommunityAlliance\DcGeneral\DataDefinition\DefaultContainer; +use ContaoCommunityAlliance\DcGeneral\DataDefinition\Definition\DefaultBasicDefinition; +use ContaoCommunityAlliance\DcGeneral\DataDefinition\Definition\ModelRelationshipDefinitionInterface; +use ContaoCommunityAlliance\DcGeneral\DataDefinition\Definition\View\ListingConfigInterface; +use ContaoCommunityAlliance\DcGeneral\DefaultEnvironment; +use ContaoCommunityAlliance\DcGeneral\EnvironmentFlatConfigRegistryInterface; +use PHPUnit\Framework\TestCase; + +/** + * @covers \ContaoCommunityAlliance\DcGeneral\Config\FlatConfigRegistry + */ +class FlatConfigRegistryTest extends TestCase +{ + public function testSetterAndGetter(): void + { + $environment = $this->getMockForAbstractClass(EnvironmentFlatConfigRegistryInterface::class); + + $configRegistry = new FlatConfigRegistry(); + + self::assertNull($configRegistry->getEnvironment()); + self::assertInstanceOf(BaseConfigRegistryInterface::class, $configRegistry->setEnvironment($environment)); + self::assertInstanceOf(EnvironmentFlatConfigRegistryInterface::class, $configRegistry->getEnvironment()); + self::assertSame($environment, $configRegistry->getEnvironment()); + } + + public function testGetBaseConfig(): void + { + // Common test settings. + $basicDefinition = + $this->getMockBuilder(DefaultBasicDefinition::class)->enableProxyingToOriginalMethods()->getMock(); + $dataDefinition = + $this->getMockBuilder(DefaultContainer::class)->disableOriginalConstructor()->getMock(); + $environment = + $this->getMockBuilder(DefaultEnvironment::class)->setMethods(['getDataDefinition'])->getMock(); + $viewDefinition = $this->createMock(Contao2BackendViewDefinitionInterface::class); + $listingConfig = $this->getMockBuilder(ListingConfigInterface::class)->getMock(); + $modelRelationShip = $this->createMock(ModelRelationshipDefinitionInterface::class); + + $viewDefinition->method('getListingConfig')->willReturn($listingConfig); + + $definition = [ + Contao2BackendViewDefinitionInterface::NAME => $viewDefinition + ]; + $dataDefinition->method('hasDefinition')->willReturnCallback( + function ($definitionName) use ($definition) { + return array_key_exists($definitionName, $definition); + } + ); + $dataDefinition->method('getDefinition')->willReturnCallback( + function ($definitionName) use ($definition) { + return $definition[$definitionName]; + } + ); + $dataDefinition->method('getModelRelationshipDefinition')->willReturn($modelRelationShip); + + $environment->method('getDataDefinition')->willReturn($dataDefinition); + + $configRegistry = new FlatConfigRegistry(); + $configRegistry->setEnvironment($environment); + + // Single data provider test settings. + $dataDefinition->method('getBasicDefinition')->willReturn($basicDefinition); + $singleDataProvider = $this->createMock(DefaultDataProvider::class); + $singleDataProviderConfig = DefaultConfig::init(); + $singleDataProvider->method('getEmptyConfig')->willReturn($singleDataProviderConfig); + $singleAdditionalFilter = ['single' => 'foo']; + + // Single data provider tests. + $environment->addDataProvider('single', $singleDataProvider); + $basicDefinition->setDataProvider('single'); + $basicDefinition->setAdditionalFilter('single', ['single' => 'foo']); + self::assertInstanceOf(ConfigInterface::class, $configRegistry->getBaseConfig()); + self::assertIsArray($singleDataProviderConfig->getFilter()); + self::assertSame($singleAdditionalFilter, $singleDataProviderConfig->getFilter()); + } +} From 5419b2a7093e88b4d6d71365a089e6a614319031 Mon Sep 17 00:00:00 2001 From: Sven Baumann Date: Sat, 10 Apr 2021 15:07:14 +0200 Subject: [PATCH 6/6] Added a new mode to the tree picker to show the output as flat --- .../View/Contao2BackendView/TreePicker.php | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/Contao/View/Contao2BackendView/TreePicker.php b/src/Contao/View/Contao2BackendView/TreePicker.php index cfbc5586d..e10ee2d69 100644 --- a/src/Contao/View/Contao2BackendView/TreePicker.php +++ b/src/Contao/View/Contao2BackendView/TreePicker.php @@ -50,6 +50,7 @@ use ContaoCommunityAlliance\DcGeneral\DataDefinition\Definition\View\ModelFormatterConfigInterface; use ContaoCommunityAlliance\DcGeneral\DataDefinition\ModelRelationship\FilterBuilder; use ContaoCommunityAlliance\DcGeneral\DC\General; +use ContaoCommunityAlliance\DcGeneral\EnvironmentFlatConfigRegistryInterface; use ContaoCommunityAlliance\DcGeneral\EnvironmentInterface; use ContaoCommunityAlliance\DcGeneral\Exception\DcGeneralRuntimeException; use ContaoCommunityAlliance\DcGeneral\Factory\DcGeneralFactory; @@ -306,7 +307,7 @@ public function getItemContainer() /** * Retrieve the environment of the item data container. * - * @return EnvironmentInterface + * @return EnvironmentInterface|EnvironmentFlatConfigRegistryInterface */ public function getEnvironment() { @@ -612,23 +613,16 @@ public function generate() protected function generatePickerUrl() { $parameter = [ - 'fieldType' => $this->fieldType, - 'sourceName' => $this->sourceName, - 'modelId' => ModelId::fromModel($this->dataContainer->getModel())->getSerialized(), - 'orderField' => $this->orderField, - 'propertyName' => $this->name + 'fieldType' => $this->fieldType, + 'sourceName' => $this->sourceName, + 'modelId' => ModelId::fromModel($this->dataContainer->getModel())->getSerialized(), + 'orderField' => $this->orderField, + 'propertyName' => $this->name, + 'orderProperty' => $this->pickerOrderProperty, + 'sortDirection' => $this->pickerSortDirection, + 'flatMode' => ($this->pickerFlatMode ?? false) ]; - if ($this->pickerOrderProperty && $this->pickerSortDirection) { - $parameter = \array_merge( - $parameter, - [ - 'orderProperty' => $this->pickerOrderProperty, - 'sortDirection' => $this->pickerSortDirection - ] - ); - } - return System::getContainer()->get('contao.picker.builder')->getUrl('cca_tree', $parameter); } @@ -1016,11 +1010,14 @@ private function treeWalkChildCollection(CollectionInterface $childCollection, M */ public function getTreeCollectionRecursive($rootId, $level = 0, $providerName = null) { - $environment = $this->getEnvironment(); - $dataDriver = $environment->getDataProvider($providerName); - $tableTreeData = $dataDriver->getEmptyCollection(); - $rootConfig = $environment->getBaseConfigRegistry()->getBaseConfig(); - $relationships = $environment->getDataDefinition()->getModelRelationshipDefinition(); + $environment = $this->getEnvironment(); + $dataDriver = $environment->getDataProvider($providerName); + $tableTreeData = $dataDriver->getEmptyCollection(); + $configRegistry = ($this->flatMode ?? ($environment instanceof EnvironmentFlatConfigRegistryInterface)) + ? $environment->getFlatConfigRegistry() + : $environment->getBaseConfigRegistry(); + $rootConfig = $configRegistry->getBaseConfig(); + $relationships = $environment->getDataDefinition()->getModelRelationshipDefinition(); if (!$rootId) { $this->prepareFilterForRootCondition(); @@ -1055,7 +1052,11 @@ private function prepareFilterForRootCondition() $environment = $this->getEnvironment(); $rootCondition = $environment->getDataDefinition()->getModelRelationshipDefinition()->getRootCondition(); - $baseConfig = $environment->getBaseConfigRegistry()->getBaseConfig(); + $configRegistry = ($this->flatMode ?? ($environment instanceof EnvironmentFlatConfigRegistryInterface)) + ? $environment->getFlatConfigRegistry() + : $environment->getBaseConfigRegistry(); + $baseConfig = $configRegistry->getBaseConfig(); + if (!$rootCondition) { return $baseConfig; }