From da76dcd7c64103e8da69de563b8c0480f8279778 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Thu, 4 Apr 2024 16:52:00 +0200 Subject: [PATCH 01/27] TASK: Allow sizes and multiplier for container Related: #22 --- Classes/Sizes/AbstractContentElement.php | 20 ++++++ Classes/Sizes/Container.php | 30 ++++++++- Classes/Sizes/ContentElement.php | 27 ++++---- Classes/Sizes/Rootline.php | 10 +++ ...r_2col_50_50_with_container_multiplier.php | 27 ++++++++ ...ntainer_2col_50_50_with_container_size.php | 27 ++++++++ ...50-50-with-container-multiplier.typoscript | 41 +++++++++++++ .../2col-50-50-with-container-size.typoscript | 41 +++++++++++++ ...ol2colWidthContainerMultiplierDatabase.php | 61 +++++++++++++++++++ .../1col2colWidthContainerSizeDatabase.php | 61 +++++++++++++++++++ Tests/Functional/ContainerTest.php | 20 ++++++ 11 files changed, 349 insertions(+), 16 deletions(-) create mode 100644 Tests/Fixtures/container_example/Configuration/TCA/Overrides/tt_content_container_2col_50_50_with_container_multiplier.php create mode 100644 Tests/Fixtures/container_example/Configuration/TCA/Overrides/tt_content_container_2col_50_50_with_container_size.php create mode 100644 Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50-with-container-multiplier.typoscript create mode 100644 Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50-with-container-size.typoscript create mode 100644 Tests/Fixtures/container_example/Test/Fixtures/1col2colWidthContainerMultiplierDatabase.php create mode 100644 Tests/Fixtures/container_example/Test/Fixtures/1col2colWidthContainerSizeDatabase.php diff --git a/Classes/Sizes/AbstractContentElement.php b/Classes/Sizes/AbstractContentElement.php index 71330e0..4ddd504 100644 --- a/Classes/Sizes/AbstractContentElement.php +++ b/Classes/Sizes/AbstractContentElement.php @@ -84,4 +84,24 @@ public function setParent(ContentElementInterface $contentElement): void $this->parent = $contentElement; } + + protected function readConfigurationByPath(string $configurationPath): array + { + $configuration = $this->configurationManager->getByPath($configurationPath); + + $multiplier = []; + $sizes = []; + + if (is_array($configuration)) { + if (isset($configuration['multiplier'])) { + $multiplier = array_map(static fn($multiplier): float => Multiplier::parse($multiplier), $configuration['multiplier']); + } + + if (isset($configuration['sizes'])) { + $sizes = array_map(static fn($size): int => (int)$size, $configuration['sizes']); + } + } + + return [$multiplier, $sizes]; + } } diff --git a/Classes/Sizes/Container.php b/Classes/Sizes/Container.php index 3d7e590..b843d54 100644 --- a/Classes/Sizes/Container.php +++ b/Classes/Sizes/Container.php @@ -27,6 +27,16 @@ final class Container extends AbstractContentElement { + /** + * @var float[] + */ + private array $multiplier = []; + + /** + * @var int[] + */ + private array $sizes = []; + private array $columns = []; private Column $activeColumn; @@ -35,6 +45,7 @@ public function __construct(array $data) { parent::__construct($data); + $this->readConfiguration(); $this->determineColumns(); } @@ -63,7 +74,7 @@ public function getActiveColumn(): Column */ public function getMultiplier(): array { - return $this->getActiveColumn()->getMultiplier(); + return $this->multiplier; } /** @@ -71,7 +82,21 @@ public function getMultiplier(): array */ public function getSizes(): array { - return $this->getActiveColumn()->getSizes(); + return $this->sizes; + } + + public function readConfiguration(): void + { + $configurationPath = implode('.', [ + 'container', + $this->contentType, + ]); + + + [$multiplier, $sizes] = $this->readConfigurationByPath($configurationPath); + + $this->multiplier = $multiplier; + $this->sizes = $sizes; } private function determineColumns(): void @@ -83,6 +108,7 @@ private function determineColumns(): void ]); $columnsByPath = $this->configurationManager->getByPath($sizesPath); + if (is_iterable($columnsByPath)) { foreach ($columnsByPath as $columnIdentifier => $columnData) { $this->columns[$columnIdentifier] = new Column($columnIdentifier, $columnData); diff --git a/Classes/Sizes/ContentElement.php b/Classes/Sizes/ContentElement.php index 8d495ae..b85e3f1 100644 --- a/Classes/Sizes/ContentElement.php +++ b/Classes/Sizes/ContentElement.php @@ -44,14 +44,20 @@ public function __construct( $this->readConfiguration(); } - public function getSizes(): array + /** + * @return float[] + */ + public function getMultiplier(): array { - return $this->sizes; + return $this->multiplier; } - public function getMultiplier(): array + /** + * @return int[] + */ + public function getSizes(): array { - return $this->multiplier; + return $this->sizes; } public function readConfiguration(): void @@ -62,16 +68,9 @@ public function readConfiguration(): void $this->fieldName, ]); - $configuration = $this->configurationManager->getByPath($configurationPath); - - if (is_array($configuration)) { - if (isset($configuration['multiplier'])) { - $this->multiplier = array_map(static fn ($multiplier): float => Multiplier::parse($multiplier), $configuration['multiplier']); - } + [$multiplier, $sizes] = $this->readConfigurationByPath($configurationPath); - if (isset($configuration['sizes'])) { - $this->sizes = array_map(static fn ($size): int => (int) $size, $configuration['sizes']); - } - } + $this->multiplier = $multiplier; + $this->sizes = $sizes; } } diff --git a/Classes/Sizes/Rootline.php b/Classes/Sizes/Rootline.php index 4fb3c3b..c29ad7f 100644 --- a/Classes/Sizes/Rootline.php +++ b/Classes/Sizes/Rootline.php @@ -148,10 +148,20 @@ private function getSizesAndMultiplierFromRootline(): array foreach ($this->rootline as $contentElement) { if ($contentElement instanceof ContentElementInterface) { + if ($contentElement instanceof Container) { + $sizes = $contentElement->getActiveColumn()->getSizes(); + if (!empty($sizes)) { + break; + } + + $multiplier[] = $contentElement->getActiveColumn()->getMultiplier(); + } + $sizes = $contentElement->getSizes(); if (!empty($sizes)) { break; } + $multiplier[] = $contentElement->getMultiplier(); } } diff --git a/Tests/Fixtures/container_example/Configuration/TCA/Overrides/tt_content_container_2col_50_50_with_container_multiplier.php b/Tests/Fixtures/container_example/Configuration/TCA/Overrides/tt_content_container_2col_50_50_with_container_multiplier.php new file mode 100644 index 0000000..7152be1 --- /dev/null +++ b/Tests/Fixtures/container_example/Configuration/TCA/Overrides/tt_content_container_2col_50_50_with_container_multiplier.php @@ -0,0 +1,27 @@ +configureContainer(new ContainerConfiguration( + $cType, + '2 Column: 50-50', + '(50% / 50%)', + [ + [ + [ + 'name' => 'Column 101', + 'colPos' => 101, + ], + [ + 'name' => 'Column 102', + 'colPos' => 102, + ], + ], + ] + )); +})(); diff --git a/Tests/Fixtures/container_example/Configuration/TCA/Overrides/tt_content_container_2col_50_50_with_container_size.php b/Tests/Fixtures/container_example/Configuration/TCA/Overrides/tt_content_container_2col_50_50_with_container_size.php new file mode 100644 index 0000000..dade616 --- /dev/null +++ b/Tests/Fixtures/container_example/Configuration/TCA/Overrides/tt_content_container_2col_50_50_with_container_size.php @@ -0,0 +1,27 @@ +configureContainer(new ContainerConfiguration( + $cType, + '2 Column: 50-50', + '(50% / 50%)', + [ + [ + [ + 'name' => 'Column 101', + 'colPos' => 101, + ], + [ + 'name' => 'Column 102', + 'colPos' => 102, + ], + ], + ] + )); +})(); diff --git a/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50-with-container-multiplier.typoscript b/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50-with-container-multiplier.typoscript new file mode 100644 index 0000000..0777761 --- /dev/null +++ b/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50-with-container-multiplier.typoscript @@ -0,0 +1,41 @@ +plugin.tx_responsiveimages { + settings { + container { + example_container-2col-50-50-with-container-multiplier { + columns { + 101 { + multiplier { + xs = 1 + sm = 1 + md = 0,5 + lg = 0,5 + xl = 0,5 + } + } + + 102 { + multiplier { + xs = 1 + sm = 1 + md = 0,5 + lg = 0,5 + xl = 0,5 + } + } + } + multiplier { + xs = 0.8 + sm = 0.8 + md = 0.8 + lg = 0.8 + xl = 0.8 + } + } + } + } +} + +tt_content.example_container-2col-50-50-with-container-multiplier < lib.containerElement +tt_content.example_container-2col-50-50-with-container-multiplier { + templateName = 2col-50-50 +} diff --git a/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50-with-container-size.typoscript b/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50-with-container-size.typoscript new file mode 100644 index 0000000..597946e --- /dev/null +++ b/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50-with-container-size.typoscript @@ -0,0 +1,41 @@ +plugin.tx_responsiveimages { + settings { + container { + example_container-2col-50-50-with-container-size { + columns { + 101 { + multiplier { + xs = 1 + sm = 1 + md = 0,5 + lg = 0,5 + xl = 0,5 + } + } + + 102 { + multiplier { + xs = 1 + sm = 1 + md = 0,5 + lg = 0,5 + xl = 0,5 + } + } + } + sizes { + xs = 600 + sm = 900 + md = 1200 + lg = 1500 + xl = 1800 + } + } + } + } +} + +tt_content.example_container-2col-50-50-with-container-size < lib.containerElement +tt_content.example_container-2col-50-50-with-container-size { + templateName = 2col-50-50 +} diff --git a/Tests/Fixtures/container_example/Test/Fixtures/1col2colWidthContainerMultiplierDatabase.php b/Tests/Fixtures/container_example/Test/Fixtures/1col2colWidthContainerMultiplierDatabase.php new file mode 100644 index 0000000..d7e9faa --- /dev/null +++ b/Tests/Fixtures/container_example/Test/Fixtures/1col2colWidthContainerMultiplierDatabase.php @@ -0,0 +1,61 @@ + [ + 0 => [ + 'uid' => '1', + 'pid' => '2', + 'hidden' => '0', + 'sorting' => '1', + 'CType' => 'example_container-1col', + 'header' => '1col', + 'deleted' => '0', + 'starttime' => '0', + 'endtime' => '0', + 'colPos' => '0', + 'sys_language_uid' => '0', + 'tx_container_parent' => '0', + ], + 1 => [ + 'uid' => '2', + 'pid' => '2', + 'hidden' => '0', + 'sorting' => '1', + 'CType' => 'example_container-2col-50-50-with-container-multiplier', + 'header' => '2col in 2col', + 'deleted' => '0', + 'starttime' => '0', + 'endtime' => '0', + 'colPos' => '101', + 'sys_language_uid' => '0', + 'tx_container_parent' => '1', + ], + 2 => [ + 'uid' => '3', + 'pid' => '2', + 'hidden' => '0', + 'sorting' => '1', + 'CType' => 'image', + 'header' => 'image in 2col in 1col', + 'deleted' => '0', + 'starttime' => '0', + 'endtime' => '0', + 'colPos' => '102', + 'sys_language_uid' => '0', + 'image' => '1', + 'tx_container_parent' => '2', + ], + ], + 'sys_file_reference' => [ + 0 => [ + 'uid' => '1', + 'pid' => '2', + 'uid_local' => '1', + 'uid_foreign' => '3', + 'tablenames' => 'tt_content', + 'fieldname' => 'image', + ], + ], +]; diff --git a/Tests/Fixtures/container_example/Test/Fixtures/1col2colWidthContainerSizeDatabase.php b/Tests/Fixtures/container_example/Test/Fixtures/1col2colWidthContainerSizeDatabase.php new file mode 100644 index 0000000..e02ec12 --- /dev/null +++ b/Tests/Fixtures/container_example/Test/Fixtures/1col2colWidthContainerSizeDatabase.php @@ -0,0 +1,61 @@ + [ + 0 => [ + 'uid' => '1', + 'pid' => '2', + 'hidden' => '0', + 'sorting' => '1', + 'CType' => 'example_container-1col', + 'header' => '1col', + 'deleted' => '0', + 'starttime' => '0', + 'endtime' => '0', + 'colPos' => '0', + 'sys_language_uid' => '0', + 'tx_container_parent' => '0', + ], + 1 => [ + 'uid' => '2', + 'pid' => '2', + 'hidden' => '0', + 'sorting' => '1', + 'CType' => 'example_container-2col-50-50-with-container-size', + 'header' => '2col in 2col', + 'deleted' => '0', + 'starttime' => '0', + 'endtime' => '0', + 'colPos' => '101', + 'sys_language_uid' => '0', + 'tx_container_parent' => '1', + ], + 2 => [ + 'uid' => '3', + 'pid' => '2', + 'hidden' => '0', + 'sorting' => '1', + 'CType' => 'image', + 'header' => 'image in 2col in 1col', + 'deleted' => '0', + 'starttime' => '0', + 'endtime' => '0', + 'colPos' => '102', + 'sys_language_uid' => '0', + 'image' => '1', + 'tx_container_parent' => '2', + ], + ], + 'sys_file_reference' => [ + 0 => [ + 'uid' => '1', + 'pid' => '2', + 'uid_local' => '1', + 'uid_foreign' => '3', + 'tablenames' => 'tt_content', + 'fieldname' => 'image', + ], + ], +]; diff --git a/Tests/Functional/ContainerTest.php b/Tests/Functional/ContainerTest.php index 42e133b..ed89065 100644 --- a/Tests/Functional/ContainerTest.php +++ b/Tests/Functional/ContainerTest.php @@ -175,6 +175,26 @@ public static function imageScalingValuesDataProvider(): iterable '4' => 'large 1600 (min-width: 1480px)', ], ]; + yield '2 Column with Container Size in 1 Column' => [ + '1col2colWidthContainerSizeDatabase.php', + [ + '0' => 'mobile 600 (max-width: 480px)', + '1' => 'mobile 900 (max-width: 767px)', + '2' => 'tablet 600 (max-width: 991px)', + '3' => 'default 750 (max-width: 1479px)', + '4' => 'large 450 (min-width: 1480px)', + ], + ]; + yield '2 Column with Container Multiplier in 1 Column' => [ + '1col2colWidthContainerMultiplierDatabase.php', + [ + '0' => 'mobile 588 (max-width: 480px)', + '1' => 'mobile 564 (max-width: 767px)', + '2' => 'tablet 370 (max-width: 991px)', + '3' => 'default 450 (max-width: 1479px)', + '4' => 'large 225 (min-width: 1480px)', + ], + ]; } #[Test] From 472aff8e7457c3f4414d3303588f008b28814ad6 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Thu, 4 Apr 2024 17:18:58 +0200 Subject: [PATCH 02/27] Cleanup: Reduce complexity of getSizesAndMultiplierFromRootline() --- Classes/Sizes/AbstractContentElement.php | 4 +- Classes/Sizes/Container.php | 1 - Classes/Sizes/Rootline.php | 50 +++++++++++++++--------- 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/Classes/Sizes/AbstractContentElement.php b/Classes/Sizes/AbstractContentElement.php index 4ddd504..153b630 100644 --- a/Classes/Sizes/AbstractContentElement.php +++ b/Classes/Sizes/AbstractContentElement.php @@ -94,11 +94,11 @@ protected function readConfigurationByPath(string $configurationPath): array if (is_array($configuration)) { if (isset($configuration['multiplier'])) { - $multiplier = array_map(static fn($multiplier): float => Multiplier::parse($multiplier), $configuration['multiplier']); + $multiplier = array_map(static fn ($multiplier): float => Multiplier::parse($multiplier), $configuration['multiplier']); } if (isset($configuration['sizes'])) { - $sizes = array_map(static fn($size): int => (int)$size, $configuration['sizes']); + $sizes = array_map(static fn ($size): int => (int) $size, $configuration['sizes']); } } diff --git a/Classes/Sizes/Container.php b/Classes/Sizes/Container.php index b843d54..cb6f890 100644 --- a/Classes/Sizes/Container.php +++ b/Classes/Sizes/Container.php @@ -92,7 +92,6 @@ public function readConfiguration(): void $this->contentType, ]); - [$multiplier, $sizes] = $this->readConfigurationByPath($configurationPath); $this->multiplier = $multiplier; diff --git a/Classes/Sizes/Rootline.php b/Classes/Sizes/Rootline.php index c29ad7f..a84ac3b 100644 --- a/Classes/Sizes/Rootline.php +++ b/Classes/Sizes/Rootline.php @@ -59,6 +59,32 @@ public function getFinalSizes(): array return $this->finalSizes; } + public function getSizesAndMultiplierFromContentElement( + mixed $contentElement, + array $sizes, + array $multiplier + ): array { + if ($contentElement instanceof ContentElementInterface) { + if ($contentElement instanceof Container) { + $sizes = $contentElement->getActiveColumn()->getSizes(); + if (!empty($sizes)) { + return [$sizes, $multiplier]; + } + + $multiplier[] = $contentElement->getActiveColumn()->getMultiplier(); + } + + $sizes = $contentElement->getSizes(); + if (!empty($sizes)) { + return [$sizes, $multiplier]; + } + + $multiplier[] = $contentElement->getMultiplier(); + } + + return [$sizes, $multiplier]; + } + private function determineBackendLayout(): void { $typoscriptFrontendController = $GLOBALS['TSFE']; @@ -144,31 +170,17 @@ private function calculateSizes(): void private function getSizesAndMultiplierFromRootline(): array { $multiplier = []; - $sizes = []; foreach ($this->rootline as $contentElement) { - if ($contentElement instanceof ContentElementInterface) { - if ($contentElement instanceof Container) { - $sizes = $contentElement->getActiveColumn()->getSizes(); - if (!empty($sizes)) { - break; - } - - $multiplier[] = $contentElement->getActiveColumn()->getMultiplier(); - } + $sizes = []; + [$sizes, $multiplier] = $this->getSizesAndMultiplierFromContentElement($contentElement, $sizes, $multiplier); - $sizes = $contentElement->getSizes(); - if (!empty($sizes)) { - break; - } - - $multiplier[] = $contentElement->getMultiplier(); + if (!empty($sizes)) { + return [$sizes, $multiplier]; } } - if (empty($sizes)) { - $sizes = $this->backendLayout->getSizes(); - } + $sizes = $this->backendLayout->getSizes(); return [$sizes, $multiplier]; } From 412b71bd5ac530abe64862163a540de7e4285165 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Fri, 5 Apr 2024 09:15:29 +0200 Subject: [PATCH 03/27] CLEANUP: Move $multiplier and $sizes to ScalungConfiguration Object Relates: #22, relates: #24 --- Classes/Sizes/AbstractContentElement.php | 25 +++++------ Classes/Sizes/BackendLayout/Column.php | 35 +++------------ Classes/Sizes/Container.php | 31 +------------ Classes/Sizes/ContentElement.php | 36 +-------------- Classes/Sizes/ContentElementInterface.php | 4 +- Classes/Sizes/Multiplier.php | 38 ---------------- Classes/Sizes/Rootline.php | 8 ++-- Classes/Sizes/ScalingConfiguration.php | 45 +++++++++++++++++++ .../Container/2col-33-66.typoscript | 12 ++--- ...50-50-with-container-multiplier.typoscript | 12 ++--- .../2col-50-50-with-container-size.typoscript | 12 ++--- .../Container/2col-50-50.typoscript | 12 ++--- .../Container/2col-66-33.typoscript | 12 ++--- .../TypoScript/Container/3col.typoscript | 18 ++++---- 14 files changed, 107 insertions(+), 193 deletions(-) delete mode 100644 Classes/Sizes/Multiplier.php create mode 100644 Classes/Sizes/ScalingConfiguration.php diff --git a/Classes/Sizes/AbstractContentElement.php b/Classes/Sizes/AbstractContentElement.php index 153b630..a3e828b 100644 --- a/Classes/Sizes/AbstractContentElement.php +++ b/Classes/Sizes/AbstractContentElement.php @@ -31,6 +31,8 @@ abstract class AbstractContentElement implements ContentElementInterface { protected ConfigurationManager $configurationManager; + protected ScalingConfiguration $scalingConfiguration; + protected int $colPos; protected string $contentType; @@ -85,23 +87,18 @@ public function setParent(ContentElementInterface $contentElement): void $this->parent = $contentElement; } - protected function readConfigurationByPath(string $configurationPath): array + public function getScalingConfiguration(): ScalingConfiguration { - $configuration = $this->configurationManager->getByPath($configurationPath); - - $multiplier = []; - $sizes = []; - - if (is_array($configuration)) { - if (isset($configuration['multiplier'])) { - $multiplier = array_map(static fn ($multiplier): float => Multiplier::parse($multiplier), $configuration['multiplier']); - } + return $this->scalingConfiguration; + } - if (isset($configuration['sizes'])) { - $sizes = array_map(static fn ($size): int => (int) $size, $configuration['sizes']); - } + protected function readConfigurationByPath(string $configurationPath): ScalingConfiguration + { + $configuration = $this->configurationManager->getByPath($configurationPath); + if (!is_array($configuration)) { + $configuration = []; } - return [$multiplier, $sizes]; + return new ScalingConfiguration($configuration); } } diff --git a/Classes/Sizes/BackendLayout/Column.php b/Classes/Sizes/BackendLayout/Column.php index 5fdccce..a6093da 100644 --- a/Classes/Sizes/BackendLayout/Column.php +++ b/Classes/Sizes/BackendLayout/Column.php @@ -23,31 +23,17 @@ * 02110-1301, USA. */ -use Codappix\ResponsiveImages\Sizes\Multiplier; +use Codappix\ResponsiveImages\Sizes\ScalingConfiguration; class Column { - /** - * @var float[] - */ - private array $multiplier = []; - - /** - * @var int[] - */ - private array $sizes = []; + protected ScalingConfiguration $scalingConfiguration; public function __construct( private readonly int $identifier, array $data ) { - if (isset($data['multiplier'])) { - $this->multiplier = array_map(static fn ($multiplier): float => Multiplier::parse($multiplier), $data['multiplier']); - } - - if (isset($data['sizes'])) { - $this->sizes = array_map(static fn ($size): int => (int) $size, $data['sizes']); - } + $this->scalingConfiguration = new ScalingConfiguration($data); } public function getIdentifier(): int @@ -55,19 +41,8 @@ public function getIdentifier(): int return $this->identifier; } - /** - * @return float[] - */ - public function getMultiplier(): array - { - return $this->multiplier; - } - - /** - * @return int[] - */ - public function getSizes(): array + public function getScalingConfiguration(): ScalingConfiguration { - return $this->sizes; + return $this->scalingConfiguration; } } diff --git a/Classes/Sizes/Container.php b/Classes/Sizes/Container.php index cb6f890..ede0777 100644 --- a/Classes/Sizes/Container.php +++ b/Classes/Sizes/Container.php @@ -27,16 +27,6 @@ final class Container extends AbstractContentElement { - /** - * @var float[] - */ - private array $multiplier = []; - - /** - * @var int[] - */ - private array $sizes = []; - private array $columns = []; private Column $activeColumn; @@ -69,22 +59,6 @@ public function getActiveColumn(): Column return $this->activeColumn; } - /** - * @return float[] - */ - public function getMultiplier(): array - { - return $this->multiplier; - } - - /** - * @return int[] - */ - public function getSizes(): array - { - return $this->sizes; - } - public function readConfiguration(): void { $configurationPath = implode('.', [ @@ -92,10 +66,7 @@ public function readConfiguration(): void $this->contentType, ]); - [$multiplier, $sizes] = $this->readConfigurationByPath($configurationPath); - - $this->multiplier = $multiplier; - $this->sizes = $sizes; + $this->scalingConfiguration = $this->readConfigurationByPath($configurationPath); } private function determineColumns(): void diff --git a/Classes/Sizes/ContentElement.php b/Classes/Sizes/ContentElement.php index b85e3f1..9176600 100644 --- a/Classes/Sizes/ContentElement.php +++ b/Classes/Sizes/ContentElement.php @@ -25,52 +25,18 @@ class ContentElement extends AbstractContentElement { - /** - * @var float[] - */ - private array $multiplier = []; - - /** - * @var int[] - */ - private array $sizes = []; - public function __construct( array $data, private readonly string $fieldName ) { parent::__construct($data); - $this->readConfiguration(); - } - - /** - * @return float[] - */ - public function getMultiplier(): array - { - return $this->multiplier; - } - - /** - * @return int[] - */ - public function getSizes(): array - { - return $this->sizes; - } - - public function readConfiguration(): void - { $configurationPath = implode('.', [ 'contentelements', $this->contentType, $this->fieldName, ]); - [$multiplier, $sizes] = $this->readConfigurationByPath($configurationPath); - - $this->multiplier = $multiplier; - $this->sizes = $sizes; + $this->scalingConfiguration = $this->readConfigurationByPath($configurationPath); } } diff --git a/Classes/Sizes/ContentElementInterface.php b/Classes/Sizes/ContentElementInterface.php index 12842bb..93eacd0 100644 --- a/Classes/Sizes/ContentElementInterface.php +++ b/Classes/Sizes/ContentElementInterface.php @@ -20,7 +20,5 @@ public function setParent(self $contentElement): void; public function getParent(): ?self; - public function getSizes(): array; - - public function getMultiplier(): array; + public function getScalingConfiguration(): ScalingConfiguration; } diff --git a/Classes/Sizes/Multiplier.php b/Classes/Sizes/Multiplier.php deleted file mode 100644 index 79f0806..0000000 --- a/Classes/Sizes/Multiplier.php +++ /dev/null @@ -1,38 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * This class only provides the functionality to parse a string to a correct - * float value. - */ -final class Multiplier -{ - public static function parse(string $value): float - { - $value = str_replace(',', '.', $value); - - return (float) $value; - } -} diff --git a/Classes/Sizes/Rootline.php b/Classes/Sizes/Rootline.php index a84ac3b..ea8754c 100644 --- a/Classes/Sizes/Rootline.php +++ b/Classes/Sizes/Rootline.php @@ -66,20 +66,20 @@ public function getSizesAndMultiplierFromContentElement( ): array { if ($contentElement instanceof ContentElementInterface) { if ($contentElement instanceof Container) { - $sizes = $contentElement->getActiveColumn()->getSizes(); + $sizes = $contentElement->getActiveColumn()->getScalingConfiguration()->getSizes(); if (!empty($sizes)) { return [$sizes, $multiplier]; } - $multiplier[] = $contentElement->getActiveColumn()->getMultiplier(); + $multiplier[] = $contentElement->getActiveColumn()->getScalingConfiguration()->getMultiplier(); } - $sizes = $contentElement->getSizes(); + $sizes = $contentElement->getScalingConfiguration()->getSizes(); if (!empty($sizes)) { return [$sizes, $multiplier]; } - $multiplier[] = $contentElement->getMultiplier(); + $multiplier[] = $contentElement->getScalingConfiguration()->getMultiplier(); } return [$sizes, $multiplier]; diff --git a/Classes/Sizes/ScalingConfiguration.php b/Classes/Sizes/ScalingConfiguration.php new file mode 100644 index 0000000..6a2fdd7 --- /dev/null +++ b/Classes/Sizes/ScalingConfiguration.php @@ -0,0 +1,45 @@ +multiplier = array_map(static fn ($multiplier): float => (float) $multiplier, $configuration['multiplier']); + } + + if (isset($configuration['sizes'])) { + $this->sizes = array_map(static fn ($size): int => (int) $size, $configuration['sizes']); + } + } + + /** + * @return float[] + */ + public function getMultiplier(): array + { + return $this->multiplier; + } + + /** + * @return int[] + */ + public function getSizes(): array + { + return $this->sizes; + } +} diff --git a/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-33-66.typoscript b/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-33-66.typoscript index 789c1d7..df04d23 100644 --- a/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-33-66.typoscript +++ b/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-33-66.typoscript @@ -7,9 +7,9 @@ plugin.tx_responsiveimages { multiplier { xs = 1 sm = 1 - md = 0,333 - lg = 0,333 - xl = 0,333 + md = 0.333 + lg = 0.333 + xl = 0.333 } } @@ -17,9 +17,9 @@ plugin.tx_responsiveimages { multiplier { xs = 1 sm = 1 - md = 0,666 - lg = 0,666 - xl = 0,666 + md = 0.666 + lg = 0.666 + xl = 0.666 } } } diff --git a/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50-with-container-multiplier.typoscript b/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50-with-container-multiplier.typoscript index 0777761..5b5673d 100644 --- a/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50-with-container-multiplier.typoscript +++ b/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50-with-container-multiplier.typoscript @@ -7,9 +7,9 @@ plugin.tx_responsiveimages { multiplier { xs = 1 sm = 1 - md = 0,5 - lg = 0,5 - xl = 0,5 + md = 0.5 + lg = 0.5 + xl = 0.5 } } @@ -17,9 +17,9 @@ plugin.tx_responsiveimages { multiplier { xs = 1 sm = 1 - md = 0,5 - lg = 0,5 - xl = 0,5 + md = 0.5 + lg = 0.5 + xl = 0.5 } } } diff --git a/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50-with-container-size.typoscript b/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50-with-container-size.typoscript index 597946e..1026963 100644 --- a/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50-with-container-size.typoscript +++ b/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50-with-container-size.typoscript @@ -7,9 +7,9 @@ plugin.tx_responsiveimages { multiplier { xs = 1 sm = 1 - md = 0,5 - lg = 0,5 - xl = 0,5 + md = 0.5 + lg = 0.5 + xl = 0.5 } } @@ -17,9 +17,9 @@ plugin.tx_responsiveimages { multiplier { xs = 1 sm = 1 - md = 0,5 - lg = 0,5 - xl = 0,5 + md = 0.5 + lg = 0.5 + xl = 0.5 } } } diff --git a/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50.typoscript b/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50.typoscript index 33a760c..bc7746f 100644 --- a/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50.typoscript +++ b/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-50-50.typoscript @@ -7,9 +7,9 @@ plugin.tx_responsiveimages { multiplier { xs = 1 sm = 1 - md = 0,5 - lg = 0,5 - xl = 0,5 + md = 0.5 + lg = 0.5 + xl = 0.5 } } @@ -17,9 +17,9 @@ plugin.tx_responsiveimages { multiplier { xs = 1 sm = 1 - md = 0,5 - lg = 0,5 - xl = 0,5 + md = 0.5 + lg = 0.5 + xl = 0.5 } } } diff --git a/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-66-33.typoscript b/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-66-33.typoscript index 4266f20..257c424 100644 --- a/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-66-33.typoscript +++ b/Tests/Fixtures/container_example/Configuration/TypoScript/Container/2col-66-33.typoscript @@ -7,9 +7,9 @@ plugin.tx_responsiveimages { multiplier { xs = 1 sm = 1 - md = 0,666 - lg = 0,666 - xl = 0,666 + md = 0.666 + lg = 0.666 + xl = 0.666 } } @@ -17,9 +17,9 @@ plugin.tx_responsiveimages { multiplier { xs = 1 sm = 1 - md = 0,333 - lg = 0,333 - xl = 0,333 + md = 0.333 + lg = 0.333 + xl = 0.333 } } } diff --git a/Tests/Fixtures/container_example/Configuration/TypoScript/Container/3col.typoscript b/Tests/Fixtures/container_example/Configuration/TypoScript/Container/3col.typoscript index 2a283ea..64d5b27 100644 --- a/Tests/Fixtures/container_example/Configuration/TypoScript/Container/3col.typoscript +++ b/Tests/Fixtures/container_example/Configuration/TypoScript/Container/3col.typoscript @@ -7,9 +7,9 @@ plugin.tx_responsiveimages { multiplier { xs = 1 sm = 1 - md = 0,333 - lg = 0,333 - xl = 0,333 + md = 0.333 + lg = 0.333 + xl = 0.333 } } @@ -17,9 +17,9 @@ plugin.tx_responsiveimages { multiplier { xs = 1 sm = 1 - md = 0,333 - lg = 0,333 - xl = 0,333 + md = 0.333 + lg = 0.333 + xl = 0.333 } } @@ -27,9 +27,9 @@ plugin.tx_responsiveimages { multiplier { xs = 1 sm = 1 - md = 0,333 - lg = 0,333 - xl = 0,333 + md = 0.333 + lg = 0.333 + xl = 0.333 } } } From 619996be37e822711f289546981e71581e1ff19e Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Fri, 5 Apr 2024 10:39:13 +0200 Subject: [PATCH 04/27] CLEANUP: Remove extra variable for readConfigurationByPath --- Classes/Sizes/Container.php | 18 +++++++----------- Classes/Sizes/ContentElement.php | 14 +++++++------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/Classes/Sizes/Container.php b/Classes/Sizes/Container.php index ede0777..1aea900 100644 --- a/Classes/Sizes/Container.php +++ b/Classes/Sizes/Container.php @@ -35,7 +35,13 @@ public function __construct(array $data) { parent::__construct($data); - $this->readConfiguration(); + $this->scalingConfiguration = $this->readConfigurationByPath( + implode('.', [ + 'container', + $this->contentType, + ]) + ); + $this->determineColumns(); } @@ -59,16 +65,6 @@ public function getActiveColumn(): Column return $this->activeColumn; } - public function readConfiguration(): void - { - $configurationPath = implode('.', [ - 'container', - $this->contentType, - ]); - - $this->scalingConfiguration = $this->readConfigurationByPath($configurationPath); - } - private function determineColumns(): void { $sizesPath = implode('.', [ diff --git a/Classes/Sizes/ContentElement.php b/Classes/Sizes/ContentElement.php index 9176600..209f038 100644 --- a/Classes/Sizes/ContentElement.php +++ b/Classes/Sizes/ContentElement.php @@ -31,12 +31,12 @@ public function __construct( ) { parent::__construct($data); - $configurationPath = implode('.', [ - 'contentelements', - $this->contentType, - $this->fieldName, - ]); - - $this->scalingConfiguration = $this->readConfigurationByPath($configurationPath); + $this->scalingConfiguration = $this->readConfigurationByPath( + implode('.', [ + 'contentelements', + $this->contentType, + $this->fieldName, + ]) + ); } } From f3adfbfcb7a224bde27aa55acc5d1621234bedc4 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Fri, 5 Apr 2024 10:43:18 +0200 Subject: [PATCH 05/27] CLEANUP: Remove superfluous $size parameter from method --- Classes/Sizes/Rootline.php | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/Classes/Sizes/Rootline.php b/Classes/Sizes/Rootline.php index ea8754c..3d9068d 100644 --- a/Classes/Sizes/Rootline.php +++ b/Classes/Sizes/Rootline.php @@ -60,28 +60,25 @@ public function getFinalSizes(): array } public function getSizesAndMultiplierFromContentElement( - mixed $contentElement, - array $sizes, + ContentElementInterface $contentElement, array $multiplier ): array { - if ($contentElement instanceof ContentElementInterface) { - if ($contentElement instanceof Container) { - $sizes = $contentElement->getActiveColumn()->getScalingConfiguration()->getSizes(); - if (!empty($sizes)) { - return [$sizes, $multiplier]; - } - - $multiplier[] = $contentElement->getActiveColumn()->getScalingConfiguration()->getMultiplier(); - } - - $sizes = $contentElement->getScalingConfiguration()->getSizes(); + if ($contentElement instanceof Container) { + $sizes = $contentElement->getActiveColumn()->getScalingConfiguration()->getSizes(); if (!empty($sizes)) { return [$sizes, $multiplier]; } - $multiplier[] = $contentElement->getScalingConfiguration()->getMultiplier(); + $multiplier[] = $contentElement->getActiveColumn()->getScalingConfiguration()->getMultiplier(); } + $sizes = $contentElement->getScalingConfiguration()->getSizes(); + if (!empty($sizes)) { + return [$sizes, $multiplier]; + } + + $multiplier[] = $contentElement->getScalingConfiguration()->getMultiplier(); + return [$sizes, $multiplier]; } @@ -172,8 +169,7 @@ private function getSizesAndMultiplierFromRootline(): array $multiplier = []; foreach ($this->rootline as $contentElement) { - $sizes = []; - [$sizes, $multiplier] = $this->getSizesAndMultiplierFromContentElement($contentElement, $sizes, $multiplier); + [$sizes, $multiplier] = $this->getSizesAndMultiplierFromContentElement($contentElement, $multiplier); if (!empty($sizes)) { return [$sizes, $multiplier]; From d0983e1eb8c0c24e7cf55e17961c0aac888a968e Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Fri, 5 Apr 2024 16:31:30 +0200 Subject: [PATCH 06/27] TASK: Refactor rootline handling Instead of iterating over the rootline, the rootline is set up so that every child knows the parent. If the child itself has no size configuration, the calculated multiplier is passed on to the parent for calculation. In this way, the complete calculation is stored out of the rootline class. New classes had to be introduced for the columns of the containers and the columns of the backend layout. A corresponding element is then added to the rootline for these columns. Related: #26 --- .../Domain/Repository/ContainerRepository.php | 37 ++++ Classes/Sizes/AbstractContentElement.php | 48 +----- Classes/Sizes/AbstractRootlineElement.php | 105 ++++++++++++ Classes/Sizes/BackendLayout.php | 73 +++----- .../Column.php => BackendLayoutColumn.php} | 32 ++-- Classes/Sizes/Container.php | 45 ----- Classes/Sizes/ContainerColumn.php | 43 +++++ Classes/Sizes/ContentElementInterface.php | 29 ++-- Classes/Sizes/Rootline.php | 158 ++++++------------ Classes/Sizes/RootlineElementInterface.php | 35 ++++ Classes/Sizes/ScalingConfiguration.php | 19 +++ ....php => 2col_66_33_ImageLeft_Database.php} | 0 .../2col_66_33_ImageRight_Database.php | 47 ++++++ Tests/Functional/ContainerTest.php | 14 +- 14 files changed, 415 insertions(+), 270 deletions(-) create mode 100644 Classes/Domain/Repository/ContainerRepository.php create mode 100644 Classes/Sizes/AbstractRootlineElement.php rename Classes/Sizes/{BackendLayout/Column.php => BackendLayoutColumn.php} (61%) create mode 100644 Classes/Sizes/ContainerColumn.php create mode 100644 Classes/Sizes/RootlineElementInterface.php rename Tests/Fixtures/container_example/Test/Fixtures/{2col_66_33_Database.php => 2col_66_33_ImageLeft_Database.php} (100%) create mode 100644 Tests/Fixtures/container_example/Test/Fixtures/2col_66_33_ImageRight_Database.php diff --git a/Classes/Domain/Repository/ContainerRepository.php b/Classes/Domain/Repository/ContainerRepository.php new file mode 100644 index 0000000..7b8da08 --- /dev/null +++ b/Classes/Domain/Repository/ContainerRepository.php @@ -0,0 +1,37 @@ +getQueryBuilderForTable('tt_content'); + $rawData = $queryBuilder + ->select('*') + ->from('tt_content') + ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($identifier, Connection::PARAM_INT))) + ->executeQuery() + ->fetchAssociative() + ; + + if ($rawData === false) { + throw new Exception("Content element '" . $identifier . "' not found."); + } + + return $rawData; + } +} diff --git a/Classes/Sizes/AbstractContentElement.php b/Classes/Sizes/AbstractContentElement.php index a3e828b..d590fd7 100644 --- a/Classes/Sizes/AbstractContentElement.php +++ b/Classes/Sizes/AbstractContentElement.php @@ -23,27 +23,20 @@ * 02110-1301, USA. */ -use Codappix\ResponsiveImages\Configuration\ConfigurationManager; use Exception; -use TYPO3\CMS\Core\Utility\GeneralUtility; -abstract class AbstractContentElement implements ContentElementInterface +abstract class AbstractContentElement extends AbstractRootlineElement implements ContentElementInterface { - protected ConfigurationManager $configurationManager; - - protected ScalingConfiguration $scalingConfiguration; - protected int $colPos; protected string $contentType; - protected array $data; + protected RootlineElementInterface $parent; - protected ContentElementInterface $parent; - - public function __construct(array $data) - { - $this->configurationManager = GeneralUtility::makeInstance(ConfigurationManager::class); + public function __construct( + protected array $data + ) { + parent::__construct(); $this->contentType = $data['CType']; $this->colPos = $data['colPos']; @@ -72,33 +65,4 @@ public function getContentType(): string { return $this->contentType; } - - public function getParent(): ?ContentElementInterface - { - return $this->parent; - } - - public function setParent(ContentElementInterface $contentElement): void - { - if ($contentElement instanceof Container) { - $contentElement->setActiveColumn($contentElement->getColumn($this->colPos)); - } - - $this->parent = $contentElement; - } - - public function getScalingConfiguration(): ScalingConfiguration - { - return $this->scalingConfiguration; - } - - protected function readConfigurationByPath(string $configurationPath): ScalingConfiguration - { - $configuration = $this->configurationManager->getByPath($configurationPath); - if (!is_array($configuration)) { - $configuration = []; - } - - return new ScalingConfiguration($configuration); - } } diff --git a/Classes/Sizes/AbstractRootlineElement.php b/Classes/Sizes/AbstractRootlineElement.php new file mode 100644 index 0000000..e365d6e --- /dev/null +++ b/Classes/Sizes/AbstractRootlineElement.php @@ -0,0 +1,105 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use Codappix\ResponsiveImages\Configuration\ConfigurationManager; +use TYPO3\CMS\Core\Utility\GeneralUtility; + +class AbstractRootlineElement +{ + protected ConfigurationManager $configurationManager; + + protected RootlineElementInterface $parent; + + protected ScalingConfiguration $scalingConfiguration; + + public function __construct() + { + $this->configurationManager = GeneralUtility::makeInstance(ConfigurationManager::class); + } + + public function getParent(): ?RootlineElementInterface + { + return $this->parent; + } + + public function setParent(RootlineElementInterface $rootlineElement): void + { + $this->parent = $rootlineElement; + } + + public function getScalingConfiguration(): ScalingConfiguration + { + return $this->scalingConfiguration; + } + + public function getFinalSize(array $multiplier): array + { + if ($this->getScalingConfiguration()->getSizes()) { + if (empty($multiplier)) { + return $this->getScalingConfiguration()->getSizes(); + } + + return $this->multiplyArray($this->getScalingConfiguration()->getSizes(), $multiplier); + } + + if (is_null($this->getParent())) { + return $this->multiplyArray($this->getScalingConfiguration()->getMultiplier(), $multiplier); + } + + return $this->getParent()->getFinalSize( + $this->multiplyArray($this->getScalingConfiguration()->getMultiplier(), $multiplier) + ); + } + + protected function multiplyArray(array $factor1, array $factor2): array + { + if (empty($factor1)) { + return $factor2; + } + if (empty($factor2)) { + return $factor1; + } + + foreach ($factor1 as $sizeName => &$size) { + if (isset($factor2[$sizeName]) === false) { + continue; + } + + $factor1[$sizeName] *= $factor2[$sizeName]; + } + + return $factor1; + } + + protected function readConfigurationByPath(string $configurationPath): ScalingConfiguration + { + $configuration = $this->configurationManager->getByPath($configurationPath); + if (!is_array($configuration)) { + $configuration = []; + } + + return new ScalingConfiguration($configuration); + } +} diff --git a/Classes/Sizes/BackendLayout.php b/Classes/Sizes/BackendLayout.php index 47d31a1..27bbfc1 100644 --- a/Classes/Sizes/BackendLayout.php +++ b/Classes/Sizes/BackendLayout.php @@ -23,68 +23,49 @@ * 02110-1301, USA. */ -use Codappix\ResponsiveImages\Configuration\ConfigurationManager; -use Codappix\ResponsiveImages\Sizes\BackendLayout\Column; -use TYPO3\CMS\Core\Utility\GeneralUtility; - -final class BackendLayout +final class BackendLayout extends AbstractRootlineElement implements RootlineElementInterface { - private array $sizes = []; - - private array $columns = []; - - private Column $activeColumn; - - private readonly ConfigurationManager $configurationManager; + /** + * @var int[] + */ + private array $columns; public function __construct( protected string $identifier ) { - $this->configurationManager = GeneralUtility::makeInstance(ConfigurationManager::class); + parent::__construct(); - $this->determineSizes(); - $this->determineColumns(); - } + $this->scalingConfiguration = $this->readConfigurationByPath( + implode('.', [ + 'backendlayouts', + $this->identifier, + ]) + ); - public function getSizes(): array - { - return $this->sizes; + $this->determineColumns(); } - public function getColumns(): array + public function getParent(): ?RootlineElementInterface { - return $this->columns; + return null; } - public function getColumn(int $columnPosition): Column + public function setParent(RootlineElementInterface $rootlineElement): void { - return $this->columns[$columnPosition]; - } - public function setActiveColumn(Column $column): void - { - $this->activeColumn = $column; } - public function getActiveColumn(): Column + public function getFinalSize(array $multiplier): array { - return $this->activeColumn; + return $this->multiplyArray($this->scalingConfiguration->getSizes(), $multiplier); } - private function determineSizes(): void + public function getColumns(): array { - $sizesPath = implode('.', [ - 'backendlayouts', - $this->identifier, - 'sizes', - ]); - - if (is_array($this->configurationManager->getByPath($sizesPath))) { - $this->sizes = $this->configurationManager->getByPath($sizesPath); - } + return $this->columns; } - private function determineColumns(): array + private function determineColumns(): void { $sizesPath = implode('.', [ 'backendlayouts', @@ -92,14 +73,8 @@ private function determineColumns(): array 'columns', ]); - $breakpointsByPath = $this->configurationManager->getByPath($sizesPath); - - if (is_iterable($breakpointsByPath)) { - foreach ($breakpointsByPath as $columnIdentifier => $columnData) { - $this->columns[$columnIdentifier] = new Column($columnIdentifier, $columnData); - } - } - - return $this->columns; + $columns = $this->configurationManager->getByPath($sizesPath); + assert(is_array($columns)); + $this->columns = array_map(static fn ($column): int => (int) $column, array_keys($columns)); } } diff --git a/Classes/Sizes/BackendLayout/Column.php b/Classes/Sizes/BackendLayoutColumn.php similarity index 61% rename from Classes/Sizes/BackendLayout/Column.php rename to Classes/Sizes/BackendLayoutColumn.php index a6093da..2b515fe 100644 --- a/Classes/Sizes/BackendLayout/Column.php +++ b/Classes/Sizes/BackendLayoutColumn.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Codappix\ResponsiveImages\Sizes\BackendLayout; +namespace Codappix\ResponsiveImages\Sizes; /* * Copyright (C) 2020 Justus Moroni @@ -23,26 +23,26 @@ * 02110-1301, USA. */ -use Codappix\ResponsiveImages\Sizes\ScalingConfiguration; - -class Column +final class BackendLayoutColumn extends AbstractRootlineElement implements RootlineElementInterface { - protected ScalingConfiguration $scalingConfiguration; - public function __construct( - private readonly int $identifier, - array $data + protected string $identifier, + protected int $column ) { - $this->scalingConfiguration = new ScalingConfiguration($data); - } - - public function getIdentifier(): int - { - return $this->identifier; + parent::__construct(); + + $this->scalingConfiguration = $this->readConfigurationByPath( + implode('.', [ + 'backendlayouts', + $this->identifier, + 'columns', + (string) $this->column, + ]) + ); } - public function getScalingConfiguration(): ScalingConfiguration + public function getColumn(): int { - return $this->scalingConfiguration; + return $this->column; } } diff --git a/Classes/Sizes/Container.php b/Classes/Sizes/Container.php index 1aea900..738914e 100644 --- a/Classes/Sizes/Container.php +++ b/Classes/Sizes/Container.php @@ -23,14 +23,8 @@ * 02110-1301, USA. */ -use Codappix\ResponsiveImages\Sizes\BackendLayout\Column; - final class Container extends AbstractContentElement { - private array $columns = []; - - private Column $activeColumn; - public function __construct(array $data) { parent::__construct($data); @@ -41,44 +35,5 @@ public function __construct(array $data) $this->contentType, ]) ); - - $this->determineColumns(); - } - - public function getColumns(): array - { - return $this->columns; - } - - public function getColumn(int $columnPosition): Column - { - return $this->columns[$columnPosition]; - } - - public function setActiveColumn(Column $column): void - { - $this->activeColumn = $column; - } - - public function getActiveColumn(): Column - { - return $this->activeColumn; - } - - private function determineColumns(): void - { - $sizesPath = implode('.', [ - 'container', - $this->contentType, - 'columns', - ]); - - $columnsByPath = $this->configurationManager->getByPath($sizesPath); - - if (is_iterable($columnsByPath)) { - foreach ($columnsByPath as $columnIdentifier => $columnData) { - $this->columns[$columnIdentifier] = new Column($columnIdentifier, $columnData); - } - } } } diff --git a/Classes/Sizes/ContainerColumn.php b/Classes/Sizes/ContainerColumn.php new file mode 100644 index 0000000..55310be --- /dev/null +++ b/Classes/Sizes/ContainerColumn.php @@ -0,0 +1,43 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +class ContainerColumn extends AbstractContentElement +{ + public function __construct( + array $data, + int $colPos + ) { + parent::__construct($data); + + $this->scalingConfiguration = $this->readConfigurationByPath( + implode('.', [ + 'container', + $this->contentType, + 'columns', + (string) $colPos, + ]) + ); + } +} diff --git a/Classes/Sizes/ContentElementInterface.php b/Classes/Sizes/ContentElementInterface.php index 93eacd0..1e2a8f5 100644 --- a/Classes/Sizes/ContentElementInterface.php +++ b/Classes/Sizes/ContentElementInterface.php @@ -4,21 +4,30 @@ namespace Codappix\ResponsiveImages\Sizes; -/** - * This class represents the content elements in the rootline of the current - * content element which is rendered. +/* + * Copyright (C) 2024 Daniel Gohlke + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. */ -interface ContentElementInterface + +interface ContentElementInterface extends RootlineElementInterface { public function getData(?string $dataIdentifier = null): mixed; public function getContentType(): string; public function getColPos(): int; - - public function setParent(self $contentElement): void; - - public function getParent(): ?self; - - public function getScalingConfiguration(): ScalingConfiguration; } diff --git a/Classes/Sizes/Rootline.php b/Classes/Sizes/Rootline.php index 3d9068d..2e0dd90 100644 --- a/Classes/Sizes/Rootline.php +++ b/Classes/Sizes/Rootline.php @@ -5,7 +5,8 @@ namespace Codappix\ResponsiveImages\Sizes; /* - * Copyright (C) 2020 Justus Moroni + * Copyright (C) 2024 Justus Moroni + * Copyright (C) 2024 Daniel Gohlke * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -24,10 +25,7 @@ */ use B13\Container\Tca\Registry; -use TYPO3\CMS\Core\Database\Connection; -use TYPO3\CMS\Core\Database\ConnectionPool; -use TYPO3\CMS\Core\Database\Query\QueryBuilder; -use TYPO3\CMS\Core\Error\Exception; +use Codappix\ResponsiveImages\Domain\Repository\ContainerRepository; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Frontend\Page\PageLayoutResolver; @@ -38,40 +36,44 @@ final class Rootline private BackendLayout $backendLayout; - private array $rootline = []; + private ContainerRepository $containerRepository; private array $finalSizes = []; private string $fieldName; - public function __construct(array $data, string $fieldName) - { + private string $backendLayoutIdentifier; + + public function __construct( + array $data, + string $fieldName + ) { + $this->containerRepository = new ContainerRepository(); + $this->determineBackendLayout(); $this->fieldName = $fieldName; - $this->contentElement = $this->determineContentElement($data); + $this->contentElement = $this->determineContentElement(null, $data); + + $this->determineRootline($this->contentElement); - $this->determineRootline(); - $this->calculateSizes(); + $this->finalSizes = $this->contentElement->getFinalSize([]); } public function getFinalSizes(): array { - return $this->finalSizes; + $sizes = $this->finalSizes; + + foreach ($sizes as $sizeName => &$size) { + $size = ceil($size); + } + + return $sizes; } public function getSizesAndMultiplierFromContentElement( ContentElementInterface $contentElement, array $multiplier ): array { - if ($contentElement instanceof Container) { - $sizes = $contentElement->getActiveColumn()->getScalingConfiguration()->getSizes(); - if (!empty($sizes)) { - return [$sizes, $multiplier]; - } - - $multiplier[] = $contentElement->getActiveColumn()->getScalingConfiguration()->getMultiplier(); - } - $sizes = $contentElement->getScalingConfiguration()->getSizes(); if (!empty($sizes)) { return [$sizes, $multiplier]; @@ -86,38 +88,45 @@ private function determineBackendLayout(): void { $typoscriptFrontendController = $GLOBALS['TSFE']; - $backendLayoutIdentifier = GeneralUtility::makeInstance(PageLayoutResolver::class) + $this->backendLayoutIdentifier = GeneralUtility::makeInstance(PageLayoutResolver::class) ->getLayoutForPage($typoscriptFrontendController->page, $typoscriptFrontendController->rootLine) ; - $this->backendLayout = new BackendLayout($backendLayoutIdentifier); + $this->backendLayout = new BackendLayout($this->backendLayoutIdentifier); } - private function determineContentElement(array $data): ContentElementInterface - { + private function determineContentElement( + ?ContentElementInterface $contentElement, + array $data + ): ContentElementInterface { if ( class_exists(Registry::class) && GeneralUtility::makeInstance(Registry::class)->isContainerElement($data['CType']) + && !is_null($contentElement) ) { - return new Container($data); - } + $newContainerColumn = new ContainerColumn($data, $contentElement->getColPos()); + $contentElement->setParent($newContainerColumn); - return new ContentElement($data, $this->fieldName); - } + $newContainer = new Container($data); + $newContainerColumn->setParent($newContainer); - private function determineRootline(): void - { - $this->rootline[] = $this->contentElement; + return $newContainer; + } + + $newContentElement = new ContentElement($data, $this->fieldName); + if (!is_null($contentElement)) { + $contentElement->setParent($newContentElement); + } - $this->parseRootline($this->contentElement); + return $newContentElement; } - private function parseRootline(ContentElementInterface $contentElement): void + private function determineRootline(ContentElementInterface $contentElement): void { - if (array_key_exists($contentElement->getColPos(), $this->backendLayout->getColumns())) { - $this->backendLayout->setActiveColumn( - $this->backendLayout->getColumn($contentElement->getColPos()) - ); + if (in_array($contentElement->getColPos(), $this->backendLayout->getColumns(), true)) { + $newBackendLayoutColumn = new BackendLayoutColumn($this->backendLayoutIdentifier, $contentElement->getColPos()); + $newBackendLayoutColumn->setParent($this->backendLayout); + $contentElement->setParent($newBackendLayoutColumn); return; } @@ -125,76 +134,13 @@ private function parseRootline(ContentElementInterface $contentElement): void if (ExtensionManagementUtility::isLoaded('b13/container')) { $parentContainer = $contentElement->getData('tx_container_parent'); assert(is_int($parentContainer)); - $parent = $this->fetchContentElementFromDatabase($parentContainer); - - $this->rootline[] = $parent; - $this->parseRootline($parent); - - $contentElement->setParent($parent); - } - } - - /** - * @throws \Doctrine\DBAL\Exception - * @throws Exception - */ - private function fetchContentElementFromDatabase(int $identifier): ContentElementInterface - { - /** @var QueryBuilder $queryBuilder */ - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content'); - $rawData = $queryBuilder - ->select('*') - ->from('tt_content') - ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($identifier, Connection::PARAM_INT))) - ->executeQuery() - ->fetchAssociative() - ; - - if ($rawData === false) { - throw new Exception("Content element '" . $identifier . "' not found."); - } - - return $this->determineContentElement($rawData); - } - - private function calculateSizes(): void - { - [$sizes, $multiplier] = $this->getSizesAndMultiplierFromRootline(); - - $this->calculateFinalSizes($sizes, $multiplier); - } - - private function getSizesAndMultiplierFromRootline(): array - { - $multiplier = []; - - foreach ($this->rootline as $contentElement) { - [$sizes, $multiplier] = $this->getSizesAndMultiplierFromContentElement($contentElement, $multiplier); - if (!empty($sizes)) { - return [$sizes, $multiplier]; - } - } - - $sizes = $this->backendLayout->getSizes(); - - return [$sizes, $multiplier]; - } - - private function calculateFinalSizes(array $sizes, array $multiplier): void - { - foreach ($sizes as $sizeName => &$size) { - foreach ($multiplier as $multiplierItem) { - if (isset($multiplierItem[$sizeName]) === false) { - continue; - } - - $size *= $multiplierItem[$sizeName]; - } + $parent = $this->determineContentElement( + $contentElement, + $this->containerRepository->findByIdentifier($parentContainer) + ); - $size = ceil($size); + $this->determineRootline($parent); } - - $this->finalSizes = $sizes; } } diff --git a/Classes/Sizes/RootlineElementInterface.php b/Classes/Sizes/RootlineElementInterface.php new file mode 100644 index 0000000..5cdbd0c --- /dev/null +++ b/Classes/Sizes/RootlineElementInterface.php @@ -0,0 +1,35 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +interface RootlineElementInterface +{ + public function getParent(): ?self; + + public function setParent(self $rootlineElement): void; + + public function getFinalSize(array $multiplier): array; + + public function getScalingConfiguration(): ScalingConfiguration; +} diff --git a/Classes/Sizes/ScalingConfiguration.php b/Classes/Sizes/ScalingConfiguration.php index 6a2fdd7..b101989 100644 --- a/Classes/Sizes/ScalingConfiguration.php +++ b/Classes/Sizes/ScalingConfiguration.php @@ -4,6 +4,25 @@ namespace Codappix\ResponsiveImages\Sizes; +/* + * Copyright (C) 2024 Daniel Gohlke + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + class ScalingConfiguration { /** diff --git a/Tests/Fixtures/container_example/Test/Fixtures/2col_66_33_Database.php b/Tests/Fixtures/container_example/Test/Fixtures/2col_66_33_ImageLeft_Database.php similarity index 100% rename from Tests/Fixtures/container_example/Test/Fixtures/2col_66_33_Database.php rename to Tests/Fixtures/container_example/Test/Fixtures/2col_66_33_ImageLeft_Database.php diff --git a/Tests/Fixtures/container_example/Test/Fixtures/2col_66_33_ImageRight_Database.php b/Tests/Fixtures/container_example/Test/Fixtures/2col_66_33_ImageRight_Database.php new file mode 100644 index 0000000..a1c4b96 --- /dev/null +++ b/Tests/Fixtures/container_example/Test/Fixtures/2col_66_33_ImageRight_Database.php @@ -0,0 +1,47 @@ + [ + 0 => [ + 'uid' => '1', + 'pid' => '2', + 'hidden' => '0', + 'sorting' => '1', + 'CType' => 'example_container-2col-66-33', + 'header' => '1col', + 'deleted' => '0', + 'starttime' => '0', + 'endtime' => '0', + 'colPos' => '0', + 'sys_language_uid' => '0', + 'tx_container_parent' => '0', + ], + 1 => [ + 'uid' => '2', + 'pid' => '2', + 'hidden' => '0', + 'sorting' => '1', + 'CType' => 'image', + 'header' => 'image in 2col', + 'deleted' => '0', + 'starttime' => '0', + 'endtime' => '0', + 'colPos' => '102', + 'sys_language_uid' => '0', + 'image' => '1', + 'tx_container_parent' => '1', + ], + ], + 'sys_file_reference' => [ + 0 => [ + 'uid' => '1', + 'pid' => '2', + 'uid_local' => '1', + 'uid_foreign' => '2', + 'tablenames' => 'tt_content', + 'fieldname' => 'image', + ], + ], +]; diff --git a/Tests/Functional/ContainerTest.php b/Tests/Functional/ContainerTest.php index ed89065..1c41226 100644 --- a/Tests/Functional/ContainerTest.php +++ b/Tests/Functional/ContainerTest.php @@ -95,8 +95,8 @@ public static function imageScalingValuesDataProvider(): iterable '4' => 'large 281 (min-width: 1480px)', ], ]; - yield '2 Column 66-33' => [ - '2col_66_33_Database.php', + yield '2 Column 66-33 Image in left Column' => [ + '2col_66_33_ImageLeft_Database.php', [ '0' => 'mobile 734 (max-width: 480px)', '1' => 'mobile 704 (max-width: 767px)', @@ -105,6 +105,16 @@ public static function imageScalingValuesDataProvider(): iterable '4' => 'large 375 (min-width: 1480px)', ], ]; + yield '2 Column 66-33 Image in right Column' => [ + '2col_66_33_ImageRight_Database.php', + [ + '0' => 'mobile 734 (max-width: 480px)', + '1' => 'mobile 704 (max-width: 767px)', + '2' => 'tablet 308 (max-width: 991px)', + '3' => 'default 375 (max-width: 1479px)', + '4' => 'large 188 (min-width: 1480px)', + ], + ]; yield '2 Column in 1 Column' => [ '1col2colDatabase.php', [ From ebe1c0cabc94899ab193205a6a253ad61a904819 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Tue, 9 Apr 2024 11:02:43 +0200 Subject: [PATCH 07/27] CLEANUP: Use DI for ContainerRepository --- .../ResponsiveImagesProcessor.php | 13 ++++++------- .../Domain/Repository/ContainerRepository.php | 11 ++++++----- Classes/Sizes/Rootline.php | 5 +---- Configuration/Services.yaml | 19 +++++++++++++++++++ 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/Classes/DataProcessing/ResponsiveImagesProcessor.php b/Classes/DataProcessing/ResponsiveImagesProcessor.php index 0d4dc8b..1d90bde 100644 --- a/Classes/DataProcessing/ResponsiveImagesProcessor.php +++ b/Classes/DataProcessing/ResponsiveImagesProcessor.php @@ -24,17 +24,15 @@ */ use Codappix\ResponsiveImages\Configuration\ConfigurationManager; +use Codappix\ResponsiveImages\Domain\Repository\ContainerRepository; use Codappix\ResponsiveImages\Sizes\Breakpoint; use Codappix\ResponsiveImages\Sizes\Rootline; use TYPO3\CMS\Core\Resource\FileInterface; -use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface; final class ResponsiveImagesProcessor implements DataProcessorInterface { - private readonly ConfigurationManager $configurationManager; - /** * @var FileInterface[] */ @@ -44,9 +42,10 @@ final class ResponsiveImagesProcessor implements DataProcessorInterface private array $contentElementSizes = []; - public function __construct() - { - $this->configurationManager = GeneralUtility::makeInstance(ConfigurationManager::class); + public function __construct( + private ConfigurationManager $configurationManager, + private ContainerRepository $containerRepository + ) { } public function process( @@ -76,7 +75,7 @@ public function process( return $processedData; } - $this->contentElementSizes = (new Rootline($processedData['data'], $fieldName))->getFinalSizes(); + $this->contentElementSizes = (new Rootline($this->containerRepository, $processedData['data'], $fieldName))->getFinalSizes(); $this->calculateFileDimensions(); $targetFieldName = (string) $cObj->stdWrapValue( diff --git a/Classes/Domain/Repository/ContainerRepository.php b/Classes/Domain/Repository/ContainerRepository.php index 7b8da08..ab4522b 100644 --- a/Classes/Domain/Repository/ContainerRepository.php +++ b/Classes/Domain/Repository/ContainerRepository.php @@ -5,21 +5,22 @@ namespace Codappix\ResponsiveImages\Domain\Repository; use TYPO3\CMS\Core\Database\Connection; -use TYPO3\CMS\Core\Database\ConnectionPool; -use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Error\Exception; -use TYPO3\CMS\Core\Utility\GeneralUtility; class ContainerRepository { + public function __construct( + private Connection $connection + ) { + } + /** * @throws \Doctrine\DBAL\Exception * @throws Exception */ public function findByIdentifier(int $identifier): array { - /** @var QueryBuilder $queryBuilder */ - $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_content'); + $queryBuilder = $this->connection->createQueryBuilder(); $rawData = $queryBuilder ->select('*') ->from('tt_content') diff --git a/Classes/Sizes/Rootline.php b/Classes/Sizes/Rootline.php index 2e0dd90..649de4f 100644 --- a/Classes/Sizes/Rootline.php +++ b/Classes/Sizes/Rootline.php @@ -36,8 +36,6 @@ final class Rootline private BackendLayout $backendLayout; - private ContainerRepository $containerRepository; - private array $finalSizes = []; private string $fieldName; @@ -45,11 +43,10 @@ final class Rootline private string $backendLayoutIdentifier; public function __construct( + private ContainerRepository $containerRepository, array $data, string $fieldName ) { - $this->containerRepository = new ContainerRepository(); - $this->determineBackendLayout(); $this->fieldName = $fieldName; $this->contentElement = $this->determineContentElement(null, $data); diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index ade47c2..a66d1e9 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -8,6 +8,14 @@ services: Codappix\ResponsiveImages\: resource: '../Classes/*' + dbconnection.tt_content: + class: 'TYPO3\CMS\Core\Database\Connection' + factory: + - '@TYPO3\CMS\Core\Database\ConnectionPool' + - 'getConnectionForTable' + arguments: + - 'tt_content' + extbaseSettings.ResponsiveImages: class: 'array' factory: @@ -18,7 +26,18 @@ services: $extensionName: 'ResponsiveImages' $pluginName: '' + Codappix\ResponsiveImages\DataProcessing\ResponsiveImagesProcessor: + public: true + arguments: + $configurationManager: '@Codappix\ResponsiveImages\Configuration\ConfigurationManager' + $containerRepository: '@Codappix\ResponsiveImages\Domain\Repository\ContainerRepository' + Codappix\ResponsiveImages\Configuration\ConfigurationManager: public: true arguments: $settings: '@extbaseSettings.ResponsiveImages' + + Codappix\ResponsiveImages\Domain\Repository\ContainerRepository: + public: true + arguments: + - '@dbconnection.tt_content' From d4402c1036c377f870916c11b56d856cd3d8fd52 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Tue, 9 Apr 2024 11:28:42 +0200 Subject: [PATCH 08/27] CLEANUP: Limit selected columns in ContainerRepository --- Classes/Domain/Repository/ContainerRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Domain/Repository/ContainerRepository.php b/Classes/Domain/Repository/ContainerRepository.php index ab4522b..f60666c 100644 --- a/Classes/Domain/Repository/ContainerRepository.php +++ b/Classes/Domain/Repository/ContainerRepository.php @@ -22,7 +22,7 @@ public function findByIdentifier(int $identifier): array { $queryBuilder = $this->connection->createQueryBuilder(); $rawData = $queryBuilder - ->select('*') + ->select('uid', 'colPos', 'CType', 'tx_container_parent') ->from('tt_content') ->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($identifier, Connection::PARAM_INT))) ->executeQuery() From a4637cab55397d5a54d1081c549ddbdbfb272cb9 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Tue, 9 Apr 2024 11:30:33 +0200 Subject: [PATCH 09/27] CLEANUP: Remove unused old method --- Classes/Sizes/Rootline.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/Classes/Sizes/Rootline.php b/Classes/Sizes/Rootline.php index 649de4f..7aaf151 100644 --- a/Classes/Sizes/Rootline.php +++ b/Classes/Sizes/Rootline.php @@ -67,20 +67,6 @@ public function getFinalSizes(): array return $sizes; } - public function getSizesAndMultiplierFromContentElement( - ContentElementInterface $contentElement, - array $multiplier - ): array { - $sizes = $contentElement->getScalingConfiguration()->getSizes(); - if (!empty($sizes)) { - return [$sizes, $multiplier]; - } - - $multiplier[] = $contentElement->getScalingConfiguration()->getMultiplier(); - - return [$sizes, $multiplier]; - } - private function determineBackendLayout(): void { $typoscriptFrontendController = $GLOBALS['TSFE']; From 01dea4cedd9d5f0baad6dfed03f191f148d619d8 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Tue, 9 Apr 2024 11:32:18 +0200 Subject: [PATCH 10/27] CLEANUP: Mark intended as abstract class as abstact --- Classes/Sizes/AbstractRootlineElement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Sizes/AbstractRootlineElement.php b/Classes/Sizes/AbstractRootlineElement.php index e365d6e..ae2c60b 100644 --- a/Classes/Sizes/AbstractRootlineElement.php +++ b/Classes/Sizes/AbstractRootlineElement.php @@ -26,7 +26,7 @@ use Codappix\ResponsiveImages\Configuration\ConfigurationManager; use TYPO3\CMS\Core\Utility\GeneralUtility; -class AbstractRootlineElement +abstract class AbstractRootlineElement { protected ConfigurationManager $configurationManager; From e78937091cbe805fc64fc28240ee7610c991530b Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Tue, 9 Apr 2024 11:38:16 +0200 Subject: [PATCH 11/27] CLEANUP: Initialize $parent with null --- Classes/Sizes/AbstractContentElement.php | 2 -- Classes/Sizes/AbstractRootlineElement.php | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Classes/Sizes/AbstractContentElement.php b/Classes/Sizes/AbstractContentElement.php index d590fd7..770c6d6 100644 --- a/Classes/Sizes/AbstractContentElement.php +++ b/Classes/Sizes/AbstractContentElement.php @@ -31,8 +31,6 @@ abstract class AbstractContentElement extends AbstractRootlineElement implements protected string $contentType; - protected RootlineElementInterface $parent; - public function __construct( protected array $data ) { diff --git a/Classes/Sizes/AbstractRootlineElement.php b/Classes/Sizes/AbstractRootlineElement.php index ae2c60b..415f725 100644 --- a/Classes/Sizes/AbstractRootlineElement.php +++ b/Classes/Sizes/AbstractRootlineElement.php @@ -30,7 +30,7 @@ abstract class AbstractRootlineElement { protected ConfigurationManager $configurationManager; - protected RootlineElementInterface $parent; + protected ?RootlineElementInterface $parent = null; protected ScalingConfiguration $scalingConfiguration; From dd182a8a1c16e6ffac157542071df69dd6f11ae7 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Tue, 9 Apr 2024 11:38:59 +0200 Subject: [PATCH 12/27] CLEANUP: Remove double initialization --- Classes/Sizes/AbstractContentElement.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Classes/Sizes/AbstractContentElement.php b/Classes/Sizes/AbstractContentElement.php index 770c6d6..7f5ec84 100644 --- a/Classes/Sizes/AbstractContentElement.php +++ b/Classes/Sizes/AbstractContentElement.php @@ -38,7 +38,6 @@ public function __construct( $this->contentType = $data['CType']; $this->colPos = $data['colPos']; - $this->data = $data; } public function getData(?string $dataIdentifier = null): mixed From 7d5e59766f97c3beef82a620b7045934159f7b47 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Tue, 9 Apr 2024 13:27:06 +0200 Subject: [PATCH 13/27] CLEANUP: Make Rootline class a factory --- .../ResponsiveImagesProcessor.php | 7 ++- .../Factory/RootlineFactory.php} | 44 ++++++++++--------- Configuration/Services.yaml | 4 -- 3 files changed, 27 insertions(+), 28 deletions(-) rename Classes/{Sizes/Rootline.php => Domain/Factory/RootlineFactory.php} (78%) diff --git a/Classes/DataProcessing/ResponsiveImagesProcessor.php b/Classes/DataProcessing/ResponsiveImagesProcessor.php index 1d90bde..8b90e3b 100644 --- a/Classes/DataProcessing/ResponsiveImagesProcessor.php +++ b/Classes/DataProcessing/ResponsiveImagesProcessor.php @@ -24,9 +24,8 @@ */ use Codappix\ResponsiveImages\Configuration\ConfigurationManager; -use Codappix\ResponsiveImages\Domain\Repository\ContainerRepository; +use Codappix\ResponsiveImages\Domain\Factory\RootlineFactory; use Codappix\ResponsiveImages\Sizes\Breakpoint; -use Codappix\ResponsiveImages\Sizes\Rootline; use TYPO3\CMS\Core\Resource\FileInterface; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface; @@ -44,7 +43,7 @@ final class ResponsiveImagesProcessor implements DataProcessorInterface public function __construct( private ConfigurationManager $configurationManager, - private ContainerRepository $containerRepository + private RootlineFactory $rootlineFactory ) { } @@ -75,7 +74,7 @@ public function process( return $processedData; } - $this->contentElementSizes = (new Rootline($this->containerRepository, $processedData['data'], $fieldName))->getFinalSizes(); + $this->contentElementSizes = $this->rootlineFactory->getFinalSizes($processedData['data'], $fieldName); $this->calculateFileDimensions(); $targetFieldName = (string) $cObj->stdWrapValue( diff --git a/Classes/Sizes/Rootline.php b/Classes/Domain/Factory/RootlineFactory.php similarity index 78% rename from Classes/Sizes/Rootline.php rename to Classes/Domain/Factory/RootlineFactory.php index 7aaf151..d093368 100644 --- a/Classes/Sizes/Rootline.php +++ b/Classes/Domain/Factory/RootlineFactory.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Codappix\ResponsiveImages\Sizes; +namespace Codappix\ResponsiveImages\Domain\Factory; /* * Copyright (C) 2024 Justus Moroni @@ -26,41 +26,44 @@ use B13\Container\Tca\Registry; use Codappix\ResponsiveImages\Domain\Repository\ContainerRepository; +use Codappix\ResponsiveImages\Sizes\BackendLayout; +use Codappix\ResponsiveImages\Sizes\BackendLayoutColumn; +use Codappix\ResponsiveImages\Sizes\Container; +use Codappix\ResponsiveImages\Sizes\ContainerColumn; +use Codappix\ResponsiveImages\Sizes\ContentElement; +use Codappix\ResponsiveImages\Sizes\ContentElementInterface; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Frontend\Page\PageLayoutResolver; -final class Rootline +final class RootlineFactory { - private readonly ContentElementInterface $contentElement; - private BackendLayout $backendLayout; - private array $finalSizes = []; - private string $fieldName; private string $backendLayoutIdentifier; public function __construct( - private ContainerRepository $containerRepository, + private readonly ContainerRepository $containerRepository, + private readonly PageLayoutResolver $pageLayoutResolver + ) { + } + + public function getFinalSizes( array $data, string $fieldName - ) { + ): array { $this->determineBackendLayout(); + $this->fieldName = $fieldName; - $this->contentElement = $this->determineContentElement(null, $data); + $contentElement = $this->determineContentElement(null, $data); - $this->determineRootline($this->contentElement); + $this->determineRootline($contentElement); - $this->finalSizes = $this->contentElement->getFinalSize([]); - } - - public function getFinalSizes(): array - { - $sizes = $this->finalSizes; + $sizes = $contentElement->getFinalSize([]); - foreach ($sizes as $sizeName => &$size) { + foreach ($sizes as &$size) { $size = ceil($size); } @@ -71,9 +74,10 @@ private function determineBackendLayout(): void { $typoscriptFrontendController = $GLOBALS['TSFE']; - $this->backendLayoutIdentifier = GeneralUtility::makeInstance(PageLayoutResolver::class) - ->getLayoutForPage($typoscriptFrontendController->page, $typoscriptFrontendController->rootLine) - ; + $this->backendLayoutIdentifier = $this->pageLayoutResolver->getLayoutForPage( + $typoscriptFrontendController->page, + $typoscriptFrontendController->rootLine + ); $this->backendLayout = new BackendLayout($this->backendLayoutIdentifier); } diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index a66d1e9..47946d2 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -28,9 +28,6 @@ services: Codappix\ResponsiveImages\DataProcessing\ResponsiveImagesProcessor: public: true - arguments: - $configurationManager: '@Codappix\ResponsiveImages\Configuration\ConfigurationManager' - $containerRepository: '@Codappix\ResponsiveImages\Domain\Repository\ContainerRepository' Codappix\ResponsiveImages\Configuration\ConfigurationManager: public: true @@ -38,6 +35,5 @@ services: $settings: '@extbaseSettings.ResponsiveImages' Codappix\ResponsiveImages\Domain\Repository\ContainerRepository: - public: true arguments: - '@dbconnection.tt_content' From ba47a7a1affcf04bc6d6bc2740adcc5e8a4766a5 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Tue, 9 Apr 2024 23:01:51 +0200 Subject: [PATCH 14/27] CLEANUP: Move new rootline element creation to factories --- .../Domain/Factory/BackendLayoutFactory.php | 54 +++++++ .../Factory/RootlineElementFactory.php} | 25 ++- Classes/Domain/Factory/RootlineFactory.php | 145 +++++++++++++----- .../Factory/ScalingFactory.php} | 43 ++---- Classes/Domain/Model/BackendLayout.php | 103 +++++++++++++ .../Model/BackendLayoutInterface.php} | 11 +- .../Model/RootlineElement.php} | 68 ++++---- .../Model}/RootlineElementInterface.php | 9 +- .../Model/Scaling.php} | 14 +- Classes/Sizes/BackendLayout.php | 80 ---------- Classes/Sizes/BackendLayoutColumn.php | 48 ------ Classes/Sizes/Container.php | 39 ----- Classes/Sizes/ContentElement.php | 42 ----- 13 files changed, 347 insertions(+), 334 deletions(-) create mode 100644 Classes/Domain/Factory/BackendLayoutFactory.php rename Classes/{Sizes/ContainerColumn.php => Domain/Factory/RootlineElementFactory.php} (63%) rename Classes/{Sizes/AbstractContentElement.php => Domain/Factory/ScalingFactory.php} (50%) create mode 100644 Classes/Domain/Model/BackendLayout.php rename Classes/{Sizes/ContentElementInterface.php => Domain/Model/BackendLayoutInterface.php} (76%) rename Classes/{Sizes/AbstractRootlineElement.php => Domain/Model/RootlineElement.php} (57%) rename Classes/{Sizes => Domain/Model}/RootlineElementInterface.php (79%) rename Classes/{Sizes/ScalingConfiguration.php => Domain/Model/Scaling.php} (81%) delete mode 100644 Classes/Sizes/BackendLayout.php delete mode 100644 Classes/Sizes/BackendLayoutColumn.php delete mode 100644 Classes/Sizes/Container.php delete mode 100644 Classes/Sizes/ContentElement.php diff --git a/Classes/Domain/Factory/BackendLayoutFactory.php b/Classes/Domain/Factory/BackendLayoutFactory.php new file mode 100644 index 0000000..9c363f2 --- /dev/null +++ b/Classes/Domain/Factory/BackendLayoutFactory.php @@ -0,0 +1,54 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use Codappix\ResponsiveImages\Configuration\ConfigurationManager; +use Codappix\ResponsiveImages\Domain\Model\BackendLayout; +use Codappix\ResponsiveImages\Domain\Model\BackendLayoutInterface; + +class BackendLayoutFactory +{ + public function __construct( + private ConfigurationManager $configurationManager, + private readonly ScalingFactory $scalingFactory + ) { + } + + public function create(string $configurationPath): BackendLayoutInterface + { + $scaling = $this->scalingFactory->getByConfigurationPath($configurationPath); + + $columns = $this->determineColumns($configurationPath . '.columns'); + + return new BackendLayout($scaling, $columns); + } + + private function determineColumns(string $configurationPath): array + { + $columns = $this->configurationManager->getByPath($configurationPath); + assert(is_array($columns)); + + return array_map(static fn ($column): int => (int) $column, array_keys($columns)); + } +} diff --git a/Classes/Sizes/ContainerColumn.php b/Classes/Domain/Factory/RootlineElementFactory.php similarity index 63% rename from Classes/Sizes/ContainerColumn.php rename to Classes/Domain/Factory/RootlineElementFactory.php index 55310be..12e0be1 100644 --- a/Classes/Sizes/ContainerColumn.php +++ b/Classes/Domain/Factory/RootlineElementFactory.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Codappix\ResponsiveImages\Sizes; +namespace Codappix\ResponsiveImages\Domain\Factory; /* * Copyright (C) 2024 Daniel Gohlke @@ -23,21 +23,20 @@ * 02110-1301, USA. */ -class ContainerColumn extends AbstractContentElement +use Codappix\ResponsiveImages\Domain\Model\RootlineElement; +use Codappix\ResponsiveImages\Domain\Model\RootlineElementInterface; + +class RootlineElementFactory { public function __construct( - array $data, - int $colPos + private readonly ScalingFactory $scalingFactory ) { - parent::__construct($data); + } + + public function create(array $data, string $configurationPath): RootlineElementInterface + { + $scaling = $this->scalingFactory->getByConfigurationPath($configurationPath); - $this->scalingConfiguration = $this->readConfigurationByPath( - implode('.', [ - 'container', - $this->contentType, - 'columns', - (string) $colPos, - ]) - ); + return new RootlineElement($scaling, $data); } } diff --git a/Classes/Domain/Factory/RootlineFactory.php b/Classes/Domain/Factory/RootlineFactory.php index d093368..572ac25 100644 --- a/Classes/Domain/Factory/RootlineFactory.php +++ b/Classes/Domain/Factory/RootlineFactory.php @@ -25,20 +25,16 @@ */ use B13\Container\Tca\Registry; +use Codappix\ResponsiveImages\Domain\Model\BackendLayoutInterface; +use Codappix\ResponsiveImages\Domain\Model\RootlineElementInterface; use Codappix\ResponsiveImages\Domain\Repository\ContainerRepository; -use Codappix\ResponsiveImages\Sizes\BackendLayout; -use Codappix\ResponsiveImages\Sizes\BackendLayoutColumn; -use Codappix\ResponsiveImages\Sizes\Container; -use Codappix\ResponsiveImages\Sizes\ContainerColumn; -use Codappix\ResponsiveImages\Sizes\ContentElement; -use Codappix\ResponsiveImages\Sizes\ContentElementInterface; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Frontend\Page\PageLayoutResolver; final class RootlineFactory { - private BackendLayout $backendLayout; + private BackendLayoutInterface $backendLayout; private string $fieldName; @@ -46,7 +42,9 @@ final class RootlineFactory public function __construct( private readonly ContainerRepository $containerRepository, - private readonly PageLayoutResolver $pageLayoutResolver + private readonly PageLayoutResolver $pageLayoutResolver, + private readonly BackendLayoutFactory $backendLayoutFactory, + private readonly RootlineElementFactory $rootlineElementFactory ) { } @@ -72,35 +70,56 @@ public function getFinalSizes( private function determineBackendLayout(): void { - $typoscriptFrontendController = $GLOBALS['TSFE']; + $tsfe = $GLOBALS['TSFE']; $this->backendLayoutIdentifier = $this->pageLayoutResolver->getLayoutForPage( - $typoscriptFrontendController->page, - $typoscriptFrontendController->rootLine + $tsfe->page, + $tsfe->rootLine ); - $this->backendLayout = new BackendLayout($this->backendLayoutIdentifier); + $this->backendLayout = $this->backendLayoutFactory->create( + $this->getConfigPathForBackendLayout() + ); + } + + private function determineRootline(RootlineElementInterface $contentElement): void + { + if (in_array($contentElement->getColPos(), $this->backendLayout->getColumns(), true)) { + $this->detarmineBackendLayout($contentElement); + + return; + } + + if (ExtensionManagementUtility::isLoaded('b13/container')) { + $parentContainer = $contentElement->getData('tx_container_parent'); + assert(is_int($parentContainer)); + + $parent = $this->determineContentElement( + $contentElement, + $this->containerRepository->findByIdentifier($parentContainer) + ); + + $this->determineRootline($parent); + } } private function determineContentElement( - ?ContentElementInterface $contentElement, + ?RootlineElementInterface $contentElement, array $data - ): ContentElementInterface { + ): RootlineElementInterface { if ( class_exists(Registry::class) && GeneralUtility::makeInstance(Registry::class)->isContainerElement($data['CType']) && !is_null($contentElement) ) { - $newContainerColumn = new ContainerColumn($data, $contentElement->getColPos()); - $contentElement->setParent($newContainerColumn); - - $newContainer = new Container($data); - $newContainerColumn->setParent($newContainer); - - return $newContainer; + return $this->determineContainer($data, $contentElement); } - $newContentElement = new ContentElement($data, $this->fieldName); + $newContentElement = $this->rootlineElementFactory->create( + $data, + $this->getConfigPathForContentElement($data['CType']) + ); + if (!is_null($contentElement)) { $contentElement->setParent($newContentElement); } @@ -108,26 +127,76 @@ class_exists(Registry::class) return $newContentElement; } - private function determineRootline(ContentElementInterface $contentElement): void + private function detarmineBackendLayout(RootlineElementInterface $contentElement): void { - if (in_array($contentElement->getColPos(), $this->backendLayout->getColumns(), true)) { - $newBackendLayoutColumn = new BackendLayoutColumn($this->backendLayoutIdentifier, $contentElement->getColPos()); - $newBackendLayoutColumn->setParent($this->backendLayout); - $contentElement->setParent($newBackendLayoutColumn); + $newBackendLayoutColumn = $this->rootlineElementFactory->create( + [], + $this->getConfigPathForBackendLayoutColumn($contentElement) + ); - return; - } + $newBackendLayoutColumn->setParent($this->backendLayout); + $contentElement->setParent($newBackendLayoutColumn); + } - if (ExtensionManagementUtility::isLoaded('b13/container')) { - $parentContainer = $contentElement->getData('tx_container_parent'); - assert(is_int($parentContainer)); + private function determineContainer(array $data, RootlineElementInterface $contentElement): RootlineElementInterface + { + $newContainerColumn = $this->rootlineElementFactory->create( + $data, + $this->getConfigPathForContainerColumn($data['CType'], $contentElement) + ); + $contentElement->setParent($newContainerColumn); - $parent = $this->determineContentElement( - $contentElement, - $this->containerRepository->findByIdentifier($parentContainer) - ); + $newContainer = $this->rootlineElementFactory->create( + $data, + $this->getConfigPathForContainer($data['CType']) + ); + $newContainerColumn->setParent($newContainer); - $this->determineRootline($parent); - } + return $newContainer; + } + + private function getConfigPathForContentElement(string $CType): string + { + return implode('.', [ + 'contentelements', + $CType, + $this->fieldName, + ]); + } + + private function getConfigPathForContainer(string $CType): string + { + return implode('.', [ + 'container', + $CType, + ]); + } + + private function getConfigPathForContainerColumn(string $CType, RootlineElementInterface $contentElement): string + { + return implode('.', [ + 'container', + $CType, + 'columns', + (string) $contentElement->getColPos(), + ]); + } + + private function getConfigPathForBackendLayout(): string + { + return implode('.', [ + 'backendlayouts', + $this->backendLayoutIdentifier, + ]); + } + + private function getConfigPathForBackendLayoutColumn(RootlineElementInterface $contentElement): string + { + return implode('.', [ + 'backendlayouts', + $this->backendLayoutIdentifier, + 'columns', + $contentElement->getColPos(), + ]); } } diff --git a/Classes/Sizes/AbstractContentElement.php b/Classes/Domain/Factory/ScalingFactory.php similarity index 50% rename from Classes/Sizes/AbstractContentElement.php rename to Classes/Domain/Factory/ScalingFactory.php index 7f5ec84..b362237 100644 --- a/Classes/Sizes/AbstractContentElement.php +++ b/Classes/Domain/Factory/ScalingFactory.php @@ -2,9 +2,10 @@ declare(strict_types=1); -namespace Codappix\ResponsiveImages\Sizes; +namespace Codappix\ResponsiveImages\Domain\Factory; /* + * Copyright (C) 2024 Justus Moroni * Copyright (C) 2024 Daniel Gohlke * * This program is free software; you can redistribute it and/or @@ -23,43 +24,27 @@ * 02110-1301, USA. */ -use Exception; +use Codappix\ResponsiveImages\Configuration\ConfigurationManager; +use Codappix\ResponsiveImages\Domain\Model\Scaling; -abstract class AbstractContentElement extends AbstractRootlineElement implements ContentElementInterface +final class ScalingFactory { - protected int $colPos; - - protected string $contentType; - public function __construct( - protected array $data + private ConfigurationManager $configurationManager ) { - parent::__construct(); - - $this->contentType = $data['CType']; - $this->colPos = $data['colPos']; } - public function getData(?string $dataIdentifier = null): mixed + public function getByConfigurationPath(string $configurationPath): Scaling { - if ($dataIdentifier === null) { - return $this->data; - } + $configuration = $this->configurationManager->getByPath($configurationPath); + $multiplier = []; + $sizes = []; - if (isset($this->data[$dataIdentifier]) === false) { - throw new Exception('No data found for key ' . $dataIdentifier . ' in $this->data.'); + if (is_array($configuration)) { + $multiplier = !empty($configuration['multiplier']) ? $configuration['multiplier'] : []; + $sizes = !empty($configuration['sizes']) ? $configuration['sizes'] : []; } - return $this->data[$dataIdentifier]; - } - - public function getColPos(): int - { - return $this->colPos; - } - - public function getContentType(): string - { - return $this->contentType; + return new Scaling($multiplier, $sizes); } } diff --git a/Classes/Domain/Model/BackendLayout.php b/Classes/Domain/Model/BackendLayout.php new file mode 100644 index 0000000..5b43e70 --- /dev/null +++ b/Classes/Domain/Model/BackendLayout.php @@ -0,0 +1,103 @@ + + * Copyright (C) 2024 Daniel Gohlke + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +class BackendLayout implements BackendLayoutInterface +{ + public function __construct( + private readonly Scaling $scaling, + private readonly array $columns + ) { + } + + public function getParent(): ?RootlineElementInterface + { + return null; + } + + public function setParent(RootlineElementInterface $rootlineElement): void + { + $rootlineElement = null; + } + + public function getScaling(): Scaling + { + return $this->scaling; + } + + public function getFinalSize(array $multiplier): array + { + if ($this->getScaling()->getSizes()) { + if (empty($multiplier)) { + return $this->getScaling()->getSizes(); + } + + return $this->multiplyArray($this->getScaling()->getSizes(), $multiplier); + } + + if (is_null($this->getParent())) { + return $this->multiplyArray($this->getScaling()->getMultiplier(), $multiplier); + } + + return $this->getParent()->getFinalSize( + $this->multiplyArray($this->getScaling()->getMultiplier(), $multiplier) + ); + } + + public function getColPos(): int + { + return 0; + } + + public function getData(?string $dataIdentifier = null): mixed + { + return null; + } + + public function getColumns(): array + { + return $this->columns; + } + + protected function multiplyArray(array $factor1, array $factor2): array + { + if (empty($factor1)) { + return $factor2; + } + if (empty($factor2)) { + return $factor1; + } + + foreach ($factor1 as $sizeName => &$size) { + if (isset($factor2[$sizeName]) === false) { + continue; + } + + $factor1[$sizeName] *= $factor2[$sizeName]; + } + + return $factor1; + } +} diff --git a/Classes/Sizes/ContentElementInterface.php b/Classes/Domain/Model/BackendLayoutInterface.php similarity index 76% rename from Classes/Sizes/ContentElementInterface.php rename to Classes/Domain/Model/BackendLayoutInterface.php index 1e2a8f5..c21870b 100644 --- a/Classes/Sizes/ContentElementInterface.php +++ b/Classes/Domain/Model/BackendLayoutInterface.php @@ -2,9 +2,10 @@ declare(strict_types=1); -namespace Codappix\ResponsiveImages\Sizes; +namespace Codappix\ResponsiveImages\Domain\Model; /* + * Copyright (C) 2024 Justus Moroni * Copyright (C) 2024 Daniel Gohlke * * This program is free software; you can redistribute it and/or @@ -23,11 +24,7 @@ * 02110-1301, USA. */ -interface ContentElementInterface extends RootlineElementInterface +interface BackendLayoutInterface extends RootlineElementInterface { - public function getData(?string $dataIdentifier = null): mixed; - - public function getContentType(): string; - - public function getColPos(): int; + public function getColumns(): array; } diff --git a/Classes/Sizes/AbstractRootlineElement.php b/Classes/Domain/Model/RootlineElement.php similarity index 57% rename from Classes/Sizes/AbstractRootlineElement.php rename to Classes/Domain/Model/RootlineElement.php index 415f725..4bbc6c6 100644 --- a/Classes/Sizes/AbstractRootlineElement.php +++ b/Classes/Domain/Model/RootlineElement.php @@ -2,9 +2,12 @@ declare(strict_types=1); -namespace Codappix\ResponsiveImages\Sizes; +namespace Codappix\ResponsiveImages\Domain\Model; + +use Exception; /* + * Copyright (C) 2024 Justus Moroni * Copyright (C) 2024 Daniel Gohlke * * This program is free software; you can redistribute it and/or @@ -23,20 +26,19 @@ * 02110-1301, USA. */ -use Codappix\ResponsiveImages\Configuration\ConfigurationManager; -use TYPO3\CMS\Core\Utility\GeneralUtility; - -abstract class AbstractRootlineElement +class RootlineElement implements RootlineElementInterface { - protected ConfigurationManager $configurationManager; - - protected ?RootlineElementInterface $parent = null; + protected int $colPos; - protected ScalingConfiguration $scalingConfiguration; + private ?RootlineElementInterface $parent = null; - public function __construct() - { - $this->configurationManager = GeneralUtility::makeInstance(ConfigurationManager::class); + public function __construct( + private readonly Scaling $scaling, + private readonly array $data + ) { + if (isset($data['colPos'])) { + $this->colPos = $data['colPos']; + } } public function getParent(): ?RootlineElementInterface @@ -49,30 +51,48 @@ public function setParent(RootlineElementInterface $rootlineElement): void $this->parent = $rootlineElement; } - public function getScalingConfiguration(): ScalingConfiguration + public function getScaling(): Scaling { - return $this->scalingConfiguration; + return $this->scaling; } public function getFinalSize(array $multiplier): array { - if ($this->getScalingConfiguration()->getSizes()) { + if ($this->getScaling()->getSizes()) { if (empty($multiplier)) { - return $this->getScalingConfiguration()->getSizes(); + return $this->getScaling()->getSizes(); } - return $this->multiplyArray($this->getScalingConfiguration()->getSizes(), $multiplier); + return $this->multiplyArray($this->getScaling()->getSizes(), $multiplier); } if (is_null($this->getParent())) { - return $this->multiplyArray($this->getScalingConfiguration()->getMultiplier(), $multiplier); + return $this->multiplyArray($this->getScaling()->getMultiplier(), $multiplier); } return $this->getParent()->getFinalSize( - $this->multiplyArray($this->getScalingConfiguration()->getMultiplier(), $multiplier) + $this->multiplyArray($this->getScaling()->getMultiplier(), $multiplier) ); } + public function getData(?string $dataIdentifier = null): mixed + { + if ($dataIdentifier === null) { + return $this->data; + } + + if (isset($this->data[$dataIdentifier]) === false) { + throw new Exception('No data found for key ' . $dataIdentifier . ' in $this->data.'); + } + + return $this->data[$dataIdentifier]; + } + + public function getColPos(): int + { + return $this->colPos; + } + protected function multiplyArray(array $factor1, array $factor2): array { if (empty($factor1)) { @@ -92,14 +112,4 @@ protected function multiplyArray(array $factor1, array $factor2): array return $factor1; } - - protected function readConfigurationByPath(string $configurationPath): ScalingConfiguration - { - $configuration = $this->configurationManager->getByPath($configurationPath); - if (!is_array($configuration)) { - $configuration = []; - } - - return new ScalingConfiguration($configuration); - } } diff --git a/Classes/Sizes/RootlineElementInterface.php b/Classes/Domain/Model/RootlineElementInterface.php similarity index 79% rename from Classes/Sizes/RootlineElementInterface.php rename to Classes/Domain/Model/RootlineElementInterface.php index 5cdbd0c..7f42274 100644 --- a/Classes/Sizes/RootlineElementInterface.php +++ b/Classes/Domain/Model/RootlineElementInterface.php @@ -2,9 +2,10 @@ declare(strict_types=1); -namespace Codappix\ResponsiveImages\Sizes; +namespace Codappix\ResponsiveImages\Domain\Model; /* + * Copyright (C) 2024 Justus Moroni * Copyright (C) 2024 Daniel Gohlke * * This program is free software; you can redistribute it and/or @@ -29,7 +30,11 @@ public function getParent(): ?self; public function setParent(self $rootlineElement): void; + public function getScaling(): Scaling; + public function getFinalSize(array $multiplier): array; - public function getScalingConfiguration(): ScalingConfiguration; + public function getColPos(): int; + + public function getData(?string $dataIdentifier = null): mixed; } diff --git a/Classes/Sizes/ScalingConfiguration.php b/Classes/Domain/Model/Scaling.php similarity index 81% rename from Classes/Sizes/ScalingConfiguration.php rename to Classes/Domain/Model/Scaling.php index b101989..27b9feb 100644 --- a/Classes/Sizes/ScalingConfiguration.php +++ b/Classes/Domain/Model/Scaling.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Codappix\ResponsiveImages\Sizes; +namespace Codappix\ResponsiveImages\Domain\Model; /* * Copyright (C) 2024 Daniel Gohlke @@ -23,7 +23,7 @@ * 02110-1301, USA. */ -class ScalingConfiguration +class Scaling { /** * @var float[] @@ -35,14 +35,14 @@ class ScalingConfiguration */ private array $sizes = []; - public function __construct(array $configuration) + public function __construct(array $multiplier, array $sizes) { - if (isset($configuration['multiplier'])) { - $this->multiplier = array_map(static fn ($multiplier): float => (float) $multiplier, $configuration['multiplier']); + if (!empty($multiplier)) { + $this->multiplier = array_map(static fn ($multiplier): float => (float) $multiplier, $multiplier); } - if (isset($configuration['sizes'])) { - $this->sizes = array_map(static fn ($size): int => (int) $size, $configuration['sizes']); + if (!empty($sizes)) { + $this->sizes = array_map(static fn ($size): int => (int) $size, $sizes); } } diff --git a/Classes/Sizes/BackendLayout.php b/Classes/Sizes/BackendLayout.php deleted file mode 100644 index 27bbfc1..0000000 --- a/Classes/Sizes/BackendLayout.php +++ /dev/null @@ -1,80 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -final class BackendLayout extends AbstractRootlineElement implements RootlineElementInterface -{ - /** - * @var int[] - */ - private array $columns; - - public function __construct( - protected string $identifier - ) { - parent::__construct(); - - $this->scalingConfiguration = $this->readConfigurationByPath( - implode('.', [ - 'backendlayouts', - $this->identifier, - ]) - ); - - $this->determineColumns(); - } - - public function getParent(): ?RootlineElementInterface - { - return null; - } - - public function setParent(RootlineElementInterface $rootlineElement): void - { - - } - - public function getFinalSize(array $multiplier): array - { - return $this->multiplyArray($this->scalingConfiguration->getSizes(), $multiplier); - } - - public function getColumns(): array - { - return $this->columns; - } - - private function determineColumns(): void - { - $sizesPath = implode('.', [ - 'backendlayouts', - $this->identifier, - 'columns', - ]); - - $columns = $this->configurationManager->getByPath($sizesPath); - assert(is_array($columns)); - $this->columns = array_map(static fn ($column): int => (int) $column, array_keys($columns)); - } -} diff --git a/Classes/Sizes/BackendLayoutColumn.php b/Classes/Sizes/BackendLayoutColumn.php deleted file mode 100644 index 2b515fe..0000000 --- a/Classes/Sizes/BackendLayoutColumn.php +++ /dev/null @@ -1,48 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -final class BackendLayoutColumn extends AbstractRootlineElement implements RootlineElementInterface -{ - public function __construct( - protected string $identifier, - protected int $column - ) { - parent::__construct(); - - $this->scalingConfiguration = $this->readConfigurationByPath( - implode('.', [ - 'backendlayouts', - $this->identifier, - 'columns', - (string) $this->column, - ]) - ); - } - - public function getColumn(): int - { - return $this->column; - } -} diff --git a/Classes/Sizes/Container.php b/Classes/Sizes/Container.php deleted file mode 100644 index 738914e..0000000 --- a/Classes/Sizes/Container.php +++ /dev/null @@ -1,39 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -final class Container extends AbstractContentElement -{ - public function __construct(array $data) - { - parent::__construct($data); - - $this->scalingConfiguration = $this->readConfigurationByPath( - implode('.', [ - 'container', - $this->contentType, - ]) - ); - } -} diff --git a/Classes/Sizes/ContentElement.php b/Classes/Sizes/ContentElement.php deleted file mode 100644 index 209f038..0000000 --- a/Classes/Sizes/ContentElement.php +++ /dev/null @@ -1,42 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -class ContentElement extends AbstractContentElement -{ - public function __construct( - array $data, - private readonly string $fieldName - ) { - parent::__construct($data); - - $this->scalingConfiguration = $this->readConfigurationByPath( - implode('.', [ - 'contentelements', - $this->contentType, - $this->fieldName, - ]) - ); - } -} From 78585e79ba03dff5dd300197840fecf6469b2a73 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Wed, 10 Apr 2024 13:41:27 +0200 Subject: [PATCH 15/27] CLEANUP: Use determineContainerColumn only one time --- Classes/Domain/Factory/RootlineFactory.php | 119 +++++++++------------ 1 file changed, 51 insertions(+), 68 deletions(-) diff --git a/Classes/Domain/Factory/RootlineFactory.php b/Classes/Domain/Factory/RootlineFactory.php index 572ac25..aa1a865 100644 --- a/Classes/Domain/Factory/RootlineFactory.php +++ b/Classes/Domain/Factory/RootlineFactory.php @@ -24,20 +24,16 @@ * 02110-1301, USA. */ -use B13\Container\Tca\Registry; use Codappix\ResponsiveImages\Domain\Model\BackendLayoutInterface; use Codappix\ResponsiveImages\Domain\Model\RootlineElementInterface; use Codappix\ResponsiveImages\Domain\Repository\ContainerRepository; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; -use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Frontend\Page\PageLayoutResolver; final class RootlineFactory { private BackendLayoutInterface $backendLayout; - private string $fieldName; - private string $backendLayoutIdentifier; public function __construct( @@ -54,8 +50,7 @@ public function getFinalSizes( ): array { $this->determineBackendLayout(); - $this->fieldName = $fieldName; - $contentElement = $this->determineContentElement(null, $data); + $contentElement = $this->determineContentElement($data, $fieldName); $this->determineRootline($contentElement); @@ -68,6 +63,19 @@ public function getFinalSizes( return $sizes; } + public function determineContainerColumn( + array $data, + RootlineElementInterface $contentElement + ): RootlineElementInterface { + $newContainerColumn = $this->rootlineElementFactory->create( + $data, + $this->getConfigPathForContainerColumn($data['CType'], $contentElement) + ); + $contentElement->setParent($newContainerColumn); + + return $newContainerColumn; + } + private function determineBackendLayout(): void { $tsfe = $GLOBALS['TSFE']; @@ -82,52 +90,7 @@ private function determineBackendLayout(): void ); } - private function determineRootline(RootlineElementInterface $contentElement): void - { - if (in_array($contentElement->getColPos(), $this->backendLayout->getColumns(), true)) { - $this->detarmineBackendLayout($contentElement); - - return; - } - - if (ExtensionManagementUtility::isLoaded('b13/container')) { - $parentContainer = $contentElement->getData('tx_container_parent'); - assert(is_int($parentContainer)); - - $parent = $this->determineContentElement( - $contentElement, - $this->containerRepository->findByIdentifier($parentContainer) - ); - - $this->determineRootline($parent); - } - } - - private function determineContentElement( - ?RootlineElementInterface $contentElement, - array $data - ): RootlineElementInterface { - if ( - class_exists(Registry::class) - && GeneralUtility::makeInstance(Registry::class)->isContainerElement($data['CType']) - && !is_null($contentElement) - ) { - return $this->determineContainer($data, $contentElement); - } - - $newContentElement = $this->rootlineElementFactory->create( - $data, - $this->getConfigPathForContentElement($data['CType']) - ); - - if (!is_null($contentElement)) { - $contentElement->setParent($newContentElement); - } - - return $newContentElement; - } - - private function detarmineBackendLayout(RootlineElementInterface $contentElement): void + private function determineBackendLayoutColumn(RootlineElementInterface $contentElement): void { $newBackendLayoutColumn = $this->rootlineElementFactory->create( [], @@ -138,13 +101,23 @@ private function detarmineBackendLayout(RootlineElementInterface $contentElement $contentElement->setParent($newBackendLayoutColumn); } - private function determineContainer(array $data, RootlineElementInterface $contentElement): RootlineElementInterface - { - $newContainerColumn = $this->rootlineElementFactory->create( + private function determineContentElement( + array $data, + string $fieldName + ): RootlineElementInterface { + return $this->rootlineElementFactory->create( $data, - $this->getConfigPathForContainerColumn($data['CType'], $contentElement) + implode('.', [ + 'contentelements', + $data['CType'], + $fieldName, + ]) ); - $contentElement->setParent($newContainerColumn); + } + + private function determineContainer(array $data, RootlineElementInterface $contentElement): RootlineElementInterface + { + $newContainerColumn = $this->determineContainerColumn($data, $contentElement); $newContainer = $this->rootlineElementFactory->create( $data, @@ -155,13 +128,25 @@ private function determineContainer(array $data, RootlineElementInterface $conte return $newContainer; } - private function getConfigPathForContentElement(string $CType): string + private function determineRootline(RootlineElementInterface $contentElement): void { - return implode('.', [ - 'contentelements', - $CType, - $this->fieldName, - ]); + if (in_array($contentElement->getColPos(), $this->backendLayout->getColumns(), true)) { + $this->determineBackendLayoutColumn($contentElement); + + return; + } + + if (ExtensionManagementUtility::isLoaded('b13/container')) { + $parentContainer = $contentElement->getData('tx_container_parent'); + assert(is_int($parentContainer)); + + $parent = $this->determineContainer( + $this->containerRepository->findByIdentifier($parentContainer), + $contentElement + ); + + $this->determineRootline($parent); + } } private function getConfigPathForContainer(string $CType): string @@ -175,8 +160,7 @@ private function getConfigPathForContainer(string $CType): string private function getConfigPathForContainerColumn(string $CType, RootlineElementInterface $contentElement): string { return implode('.', [ - 'container', - $CType, + $this->getConfigPathForContainer($CType), 'columns', (string) $contentElement->getColPos(), ]); @@ -193,10 +177,9 @@ private function getConfigPathForBackendLayout(): string private function getConfigPathForBackendLayoutColumn(RootlineElementInterface $contentElement): string { return implode('.', [ - 'backendlayouts', - $this->backendLayoutIdentifier, + $this->getConfigPathForBackendLayout(), 'columns', - $contentElement->getColPos(), + (string) $contentElement->getColPos(), ]); } } From b9e01619ee1ddf1eb5e6fdb31fec07ae7cbecf91 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Wed, 10 Apr 2024 13:52:03 +0200 Subject: [PATCH 16/27] CLEANUP: Use arrays for retrieving information from configuration --- .../Configuration/ConfigurationManager.php | 8 +- .../ResponsiveImagesProcessor.php | 2 +- .../Domain/Factory/BackendLayoutFactory.php | 10 ++- .../Domain/Factory/RootlineElementFactory.php | 2 +- Classes/Domain/Factory/RootlineFactory.php | 86 ++++++++----------- Classes/Domain/Factory/ScalingFactory.php | 2 +- 6 files changed, 47 insertions(+), 63 deletions(-) diff --git a/Classes/Configuration/ConfigurationManager.php b/Classes/Configuration/ConfigurationManager.php index 5b50bb1..449d147 100644 --- a/Classes/Configuration/ConfigurationManager.php +++ b/Classes/Configuration/ConfigurationManager.php @@ -40,13 +40,13 @@ public function get(): array return $this->settings; } - public function isValidPath(string $path): bool + public function isValidPath(array|string $path): bool { - return ArrayUtility::isValidPath($this->settings, $path, '.'); + return ArrayUtility::isValidPath($this->settings, $path); } - public function getByPath(string $path): mixed + public function getByPath(array|string $path): mixed { - return ArrayUtility::getValueByPath($this->settings, $path, '.'); + return ArrayUtility::getValueByPath($this->settings, $path); } } diff --git a/Classes/DataProcessing/ResponsiveImagesProcessor.php b/Classes/DataProcessing/ResponsiveImagesProcessor.php index 8b90e3b..e744c31 100644 --- a/Classes/DataProcessing/ResponsiveImagesProcessor.php +++ b/Classes/DataProcessing/ResponsiveImagesProcessor.php @@ -125,7 +125,7 @@ private function getBreakpoints(): array { $breakpoints = []; - $breakpointsByPath = $this->configurationManager->getByPath('breakpoints'); + $breakpointsByPath = $this->configurationManager->getByPath(['breakpoints']); if (is_iterable($breakpointsByPath)) { foreach ($breakpointsByPath as $breakpointIdentifier => $breakpointData) { diff --git a/Classes/Domain/Factory/BackendLayoutFactory.php b/Classes/Domain/Factory/BackendLayoutFactory.php index 9c363f2..4897c33 100644 --- a/Classes/Domain/Factory/BackendLayoutFactory.php +++ b/Classes/Domain/Factory/BackendLayoutFactory.php @@ -30,21 +30,23 @@ class BackendLayoutFactory { public function __construct( - private ConfigurationManager $configurationManager, + private readonly ConfigurationManager $configurationManager, private readonly ScalingFactory $scalingFactory ) { } - public function create(string $configurationPath): BackendLayoutInterface + public function create(array $configurationPath): BackendLayoutInterface { $scaling = $this->scalingFactory->getByConfigurationPath($configurationPath); - $columns = $this->determineColumns($configurationPath . '.columns'); + $configurationPath[] = 'columns'; + + $columns = $this->determineColumns($configurationPath); return new BackendLayout($scaling, $columns); } - private function determineColumns(string $configurationPath): array + private function determineColumns(array $configurationPath): array { $columns = $this->configurationManager->getByPath($configurationPath); assert(is_array($columns)); diff --git a/Classes/Domain/Factory/RootlineElementFactory.php b/Classes/Domain/Factory/RootlineElementFactory.php index 12e0be1..cb58e48 100644 --- a/Classes/Domain/Factory/RootlineElementFactory.php +++ b/Classes/Domain/Factory/RootlineElementFactory.php @@ -33,7 +33,7 @@ public function __construct( ) { } - public function create(array $data, string $configurationPath): RootlineElementInterface + public function create(array $data, array|string $configurationPath): RootlineElementInterface { $scaling = $this->scalingFactory->getByConfigurationPath($configurationPath); diff --git a/Classes/Domain/Factory/RootlineFactory.php b/Classes/Domain/Factory/RootlineFactory.php index aa1a865..4085b95 100644 --- a/Classes/Domain/Factory/RootlineFactory.php +++ b/Classes/Domain/Factory/RootlineFactory.php @@ -69,7 +69,12 @@ public function determineContainerColumn( ): RootlineElementInterface { $newContainerColumn = $this->rootlineElementFactory->create( $data, - $this->getConfigPathForContainerColumn($data['CType'], $contentElement) + [ + 'container', + $data['CType'], + 'columns', + (string) $contentElement->getColPos(), + ] ); $contentElement->setParent($newContainerColumn); @@ -86,7 +91,10 @@ private function determineBackendLayout(): void ); $this->backendLayout = $this->backendLayoutFactory->create( - $this->getConfigPathForBackendLayout() + [ + 'backendlayouts', + $this->backendLayoutIdentifier, + ] ); } @@ -94,40 +102,48 @@ private function determineBackendLayoutColumn(RootlineElementInterface $contentE { $newBackendLayoutColumn = $this->rootlineElementFactory->create( [], - $this->getConfigPathForBackendLayoutColumn($contentElement) + [ + 'backendlayouts', + $this->backendLayoutIdentifier, + 'columns', + (string) $contentElement->getColPos(), + ] ); $newBackendLayoutColumn->setParent($this->backendLayout); $contentElement->setParent($newBackendLayoutColumn); } - private function determineContentElement( - array $data, - string $fieldName - ): RootlineElementInterface { - return $this->rootlineElementFactory->create( - $data, - implode('.', [ - 'contentelements', - $data['CType'], - $fieldName, - ]) - ); - } - private function determineContainer(array $data, RootlineElementInterface $contentElement): RootlineElementInterface { $newContainerColumn = $this->determineContainerColumn($data, $contentElement); $newContainer = $this->rootlineElementFactory->create( $data, - $this->getConfigPathForContainer($data['CType']) + [ + 'container', + $data['CType'], + ] ); $newContainerColumn->setParent($newContainer); return $newContainer; } + private function determineContentElement( + array $data, + string $fieldName + ): RootlineElementInterface { + return $this->rootlineElementFactory->create( + $data, + [ + 'contentelements', + $data['CType'], + $fieldName, + ] + ); + } + private function determineRootline(RootlineElementInterface $contentElement): void { if (in_array($contentElement->getColPos(), $this->backendLayout->getColumns(), true)) { @@ -148,38 +164,4 @@ private function determineRootline(RootlineElementInterface $contentElement): vo $this->determineRootline($parent); } } - - private function getConfigPathForContainer(string $CType): string - { - return implode('.', [ - 'container', - $CType, - ]); - } - - private function getConfigPathForContainerColumn(string $CType, RootlineElementInterface $contentElement): string - { - return implode('.', [ - $this->getConfigPathForContainer($CType), - 'columns', - (string) $contentElement->getColPos(), - ]); - } - - private function getConfigPathForBackendLayout(): string - { - return implode('.', [ - 'backendlayouts', - $this->backendLayoutIdentifier, - ]); - } - - private function getConfigPathForBackendLayoutColumn(RootlineElementInterface $contentElement): string - { - return implode('.', [ - $this->getConfigPathForBackendLayout(), - 'columns', - (string) $contentElement->getColPos(), - ]); - } } diff --git a/Classes/Domain/Factory/ScalingFactory.php b/Classes/Domain/Factory/ScalingFactory.php index b362237..83ce0c4 100644 --- a/Classes/Domain/Factory/ScalingFactory.php +++ b/Classes/Domain/Factory/ScalingFactory.php @@ -34,7 +34,7 @@ public function __construct( ) { } - public function getByConfigurationPath(string $configurationPath): Scaling + public function getByConfigurationPath(array|string $configurationPath): Scaling { $configuration = $this->configurationManager->getByPath($configurationPath); $multiplier = []; From 83b04a3b02466628f13a82ff0d8feddbdd30ad46 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Wed, 10 Apr 2024 20:21:15 +0200 Subject: [PATCH 17/27] CLEANUP: Replace BackendLayout with exiting RootlineElement --- .../ResponsiveImagesProcessor.php | 3 +- .../Domain/Factory/BackendLayoutFactory.php | 56 ---------- Classes/Domain/Factory/RootlineFactory.php | 74 ++++++++----- Classes/Domain/Model/BackendLayout.php | 103 ------------------ Classes/Domain/Model/Rootline.php | 44 ++++++++ Classes/Domain/Model/RootlineElement.php | 4 +- ...outInterface.php => RootlineInterface.php} | 4 +- 7 files changed, 95 insertions(+), 193 deletions(-) delete mode 100644 Classes/Domain/Factory/BackendLayoutFactory.php delete mode 100644 Classes/Domain/Model/BackendLayout.php create mode 100644 Classes/Domain/Model/Rootline.php rename Classes/Domain/Model/{BackendLayoutInterface.php => RootlineInterface.php} (89%) diff --git a/Classes/DataProcessing/ResponsiveImagesProcessor.php b/Classes/DataProcessing/ResponsiveImagesProcessor.php index e744c31..a85a8ee 100644 --- a/Classes/DataProcessing/ResponsiveImagesProcessor.php +++ b/Classes/DataProcessing/ResponsiveImagesProcessor.php @@ -74,7 +74,8 @@ public function process( return $processedData; } - $this->contentElementSizes = $this->rootlineFactory->getFinalSizes($processedData['data'], $fieldName); + $rootline = $this->rootlineFactory->create($processedData['data'], $fieldName); + $this->contentElementSizes = $rootline->getFinalSize(); $this->calculateFileDimensions(); $targetFieldName = (string) $cObj->stdWrapValue( diff --git a/Classes/Domain/Factory/BackendLayoutFactory.php b/Classes/Domain/Factory/BackendLayoutFactory.php deleted file mode 100644 index 4897c33..0000000 --- a/Classes/Domain/Factory/BackendLayoutFactory.php +++ /dev/null @@ -1,56 +0,0 @@ - - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -use Codappix\ResponsiveImages\Configuration\ConfigurationManager; -use Codappix\ResponsiveImages\Domain\Model\BackendLayout; -use Codappix\ResponsiveImages\Domain\Model\BackendLayoutInterface; - -class BackendLayoutFactory -{ - public function __construct( - private readonly ConfigurationManager $configurationManager, - private readonly ScalingFactory $scalingFactory - ) { - } - - public function create(array $configurationPath): BackendLayoutInterface - { - $scaling = $this->scalingFactory->getByConfigurationPath($configurationPath); - - $configurationPath[] = 'columns'; - - $columns = $this->determineColumns($configurationPath); - - return new BackendLayout($scaling, $columns); - } - - private function determineColumns(array $configurationPath): array - { - $columns = $this->configurationManager->getByPath($configurationPath); - assert(is_array($columns)); - - return array_map(static fn ($column): int => (int) $column, array_keys($columns)); - } -} diff --git a/Classes/Domain/Factory/RootlineFactory.php b/Classes/Domain/Factory/RootlineFactory.php index 4085b95..08e7c40 100644 --- a/Classes/Domain/Factory/RootlineFactory.php +++ b/Classes/Domain/Factory/RootlineFactory.php @@ -24,7 +24,8 @@ * 02110-1301, USA. */ -use Codappix\ResponsiveImages\Domain\Model\BackendLayoutInterface; +use Codappix\ResponsiveImages\Configuration\ConfigurationManager; +use Codappix\ResponsiveImages\Domain\Model\Rootline; use Codappix\ResponsiveImages\Domain\Model\RootlineElementInterface; use Codappix\ResponsiveImages\Domain\Repository\ContainerRepository; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; @@ -32,38 +33,36 @@ final class RootlineFactory { - private BackendLayoutInterface $backendLayout; + public array $columns = []; + + private RootlineElementInterface $backendLayout; + + private RootlineElementInterface $contentElement; private string $backendLayoutIdentifier; public function __construct( + private readonly ConfigurationManager $configurationManager, private readonly ContainerRepository $containerRepository, private readonly PageLayoutResolver $pageLayoutResolver, - private readonly BackendLayoutFactory $backendLayoutFactory, private readonly RootlineElementFactory $rootlineElementFactory ) { } - public function getFinalSizes( + public function create( array $data, string $fieldName - ): array { - $this->determineBackendLayout(); - - $contentElement = $this->determineContentElement($data, $fieldName); + ): Rootline { + $this->createBackendLayoutRootlineElement(); + $this->determineBackendLayoutColumns(); - $this->determineRootline($contentElement); - - $sizes = $contentElement->getFinalSize([]); - - foreach ($sizes as &$size) { - $size = ceil($size); - } + $this->createContentElementRootlineElement($data, $fieldName); + $this->determineRootline($this->contentElement); - return $sizes; + return new Rootline($this->contentElement); } - public function determineContainerColumn( + public function createContainerColumnRootlineElement( array $data, RootlineElementInterface $contentElement ): RootlineElementInterface { @@ -81,7 +80,21 @@ public function determineContainerColumn( return $newContainerColumn; } - private function determineBackendLayout(): void + public function determineBackendLayoutColumns(): void + { + $columns = $this->configurationManager->getByPath( + [ + 'backendlayouts', + $this->backendLayoutIdentifier, + 'columns', + ] + ); + + assert(is_array($columns)); + $this->columns = array_map(static fn ($column): int => (int) $column, array_keys($columns)); + } + + private function createBackendLayoutRootlineElement(): void { $tsfe = $GLOBALS['TSFE']; @@ -90,7 +103,8 @@ private function determineBackendLayout(): void $tsfe->rootLine ); - $this->backendLayout = $this->backendLayoutFactory->create( + $this->backendLayout = $this->rootlineElementFactory->create( + [], [ 'backendlayouts', $this->backendLayoutIdentifier, @@ -98,7 +112,7 @@ private function determineBackendLayout(): void ); } - private function determineBackendLayoutColumn(RootlineElementInterface $contentElement): void + private function createBackendLayoutColumnRootlineElement(RootlineElementInterface $contentElement): void { $newBackendLayoutColumn = $this->rootlineElementFactory->create( [], @@ -114,9 +128,11 @@ private function determineBackendLayoutColumn(RootlineElementInterface $contentE $contentElement->setParent($newBackendLayoutColumn); } - private function determineContainer(array $data, RootlineElementInterface $contentElement): RootlineElementInterface - { - $newContainerColumn = $this->determineContainerColumn($data, $contentElement); + private function createContainerRootlineElement( + array $data, + RootlineElementInterface $contentElement + ): RootlineElementInterface { + $newContainerColumn = $this->createContainerColumnRootlineElement($data, $contentElement); $newContainer = $this->rootlineElementFactory->create( $data, @@ -130,11 +146,11 @@ private function determineContainer(array $data, RootlineElementInterface $conte return $newContainer; } - private function determineContentElement( + private function createContentElementRootlineElement( array $data, string $fieldName - ): RootlineElementInterface { - return $this->rootlineElementFactory->create( + ): void { + $this->contentElement = $this->rootlineElementFactory->create( $data, [ 'contentelements', @@ -146,8 +162,8 @@ private function determineContentElement( private function determineRootline(RootlineElementInterface $contentElement): void { - if (in_array($contentElement->getColPos(), $this->backendLayout->getColumns(), true)) { - $this->determineBackendLayoutColumn($contentElement); + if (in_array($contentElement->getColPos(), $this->columns, true)) { + $this->createBackendLayoutColumnRootlineElement($contentElement); return; } @@ -156,7 +172,7 @@ private function determineRootline(RootlineElementInterface $contentElement): vo $parentContainer = $contentElement->getData('tx_container_parent'); assert(is_int($parentContainer)); - $parent = $this->determineContainer( + $parent = $this->createContainerRootlineElement( $this->containerRepository->findByIdentifier($parentContainer), $contentElement ); diff --git a/Classes/Domain/Model/BackendLayout.php b/Classes/Domain/Model/BackendLayout.php deleted file mode 100644 index 5b43e70..0000000 --- a/Classes/Domain/Model/BackendLayout.php +++ /dev/null @@ -1,103 +0,0 @@ - - * Copyright (C) 2024 Daniel Gohlke - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -class BackendLayout implements BackendLayoutInterface -{ - public function __construct( - private readonly Scaling $scaling, - private readonly array $columns - ) { - } - - public function getParent(): ?RootlineElementInterface - { - return null; - } - - public function setParent(RootlineElementInterface $rootlineElement): void - { - $rootlineElement = null; - } - - public function getScaling(): Scaling - { - return $this->scaling; - } - - public function getFinalSize(array $multiplier): array - { - if ($this->getScaling()->getSizes()) { - if (empty($multiplier)) { - return $this->getScaling()->getSizes(); - } - - return $this->multiplyArray($this->getScaling()->getSizes(), $multiplier); - } - - if (is_null($this->getParent())) { - return $this->multiplyArray($this->getScaling()->getMultiplier(), $multiplier); - } - - return $this->getParent()->getFinalSize( - $this->multiplyArray($this->getScaling()->getMultiplier(), $multiplier) - ); - } - - public function getColPos(): int - { - return 0; - } - - public function getData(?string $dataIdentifier = null): mixed - { - return null; - } - - public function getColumns(): array - { - return $this->columns; - } - - protected function multiplyArray(array $factor1, array $factor2): array - { - if (empty($factor1)) { - return $factor2; - } - if (empty($factor2)) { - return $factor1; - } - - foreach ($factor1 as $sizeName => &$size) { - if (isset($factor2[$sizeName]) === false) { - continue; - } - - $factor1[$sizeName] *= $factor2[$sizeName]; - } - - return $factor1; - } -} diff --git a/Classes/Domain/Model/Rootline.php b/Classes/Domain/Model/Rootline.php new file mode 100644 index 0000000..d9e803e --- /dev/null +++ b/Classes/Domain/Model/Rootline.php @@ -0,0 +1,44 @@ + + * Copyright (C) 2024 Daniel Gohlke + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +class Rootline implements RootlineInterface +{ + public function __construct( + private readonly RootlineElementInterface $rootlineElement + ) { + } + + public function getFinalSize(): array + { + $finalSize = $this->rootlineElement->getFinalSize([]); + + foreach ($finalSize as &$size) { + $size = ceil($size); + } + + return $finalSize; + } +} diff --git a/Classes/Domain/Model/RootlineElement.php b/Classes/Domain/Model/RootlineElement.php index 4bbc6c6..1debbe6 100644 --- a/Classes/Domain/Model/RootlineElement.php +++ b/Classes/Domain/Model/RootlineElement.php @@ -4,8 +4,6 @@ namespace Codappix\ResponsiveImages\Domain\Model; -use Exception; - /* * Copyright (C) 2024 Justus Moroni * Copyright (C) 2024 Daniel Gohlke @@ -26,6 +24,8 @@ * 02110-1301, USA. */ +use Exception; + class RootlineElement implements RootlineElementInterface { protected int $colPos; diff --git a/Classes/Domain/Model/BackendLayoutInterface.php b/Classes/Domain/Model/RootlineInterface.php similarity index 89% rename from Classes/Domain/Model/BackendLayoutInterface.php rename to Classes/Domain/Model/RootlineInterface.php index c21870b..7f8f4e3 100644 --- a/Classes/Domain/Model/BackendLayoutInterface.php +++ b/Classes/Domain/Model/RootlineInterface.php @@ -24,7 +24,7 @@ * 02110-1301, USA. */ -interface BackendLayoutInterface extends RootlineElementInterface +interface RootlineInterface { - public function getColumns(): array; + public function getFinalSize(): array; } From 3dc622cb5ccc7f90481f2eee7ba51d765c2187b4 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Wed, 10 Apr 2024 20:25:22 +0200 Subject: [PATCH 18/27] CLEANUP: Move Breakpoint to Domain/Model folder --- Classes/DataProcessing/ResponsiveImagesProcessor.php | 2 +- Classes/{Sizes => Domain/Model}/Breakpoint.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename Classes/{Sizes => Domain/Model}/Breakpoint.php (97%) diff --git a/Classes/DataProcessing/ResponsiveImagesProcessor.php b/Classes/DataProcessing/ResponsiveImagesProcessor.php index a85a8ee..357c455 100644 --- a/Classes/DataProcessing/ResponsiveImagesProcessor.php +++ b/Classes/DataProcessing/ResponsiveImagesProcessor.php @@ -25,7 +25,7 @@ use Codappix\ResponsiveImages\Configuration\ConfigurationManager; use Codappix\ResponsiveImages\Domain\Factory\RootlineFactory; -use Codappix\ResponsiveImages\Sizes\Breakpoint; +use Codappix\ResponsiveImages\Domain\Model\Breakpoint; use TYPO3\CMS\Core\Resource\FileInterface; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface; diff --git a/Classes/Sizes/Breakpoint.php b/Classes/Domain/Model/Breakpoint.php similarity index 97% rename from Classes/Sizes/Breakpoint.php rename to Classes/Domain/Model/Breakpoint.php index a295d9f..e197498 100644 --- a/Classes/Sizes/Breakpoint.php +++ b/Classes/Domain/Model/Breakpoint.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Codappix\ResponsiveImages\Sizes; +namespace Codappix\ResponsiveImages\Domain\Model; /* * Copyright (C) 2020 Justus Moroni From 931c6bf625a23b2a34a8ac72f46b49e4d17d15c8 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Wed, 10 Apr 2024 20:31:53 +0200 Subject: [PATCH 19/27] CLEANUP: Create Breakpoints in BreakpointFactory --- .../ResponsiveImagesProcessor.php | 23 ++------ Classes/Domain/Factory/BreakpointFactory.php | 54 +++++++++++++++++++ Classes/Domain/Factory/ScalingFactory.php | 2 +- 3 files changed, 58 insertions(+), 21 deletions(-) create mode 100644 Classes/Domain/Factory/BreakpointFactory.php diff --git a/Classes/DataProcessing/ResponsiveImagesProcessor.php b/Classes/DataProcessing/ResponsiveImagesProcessor.php index 357c455..4da1eac 100644 --- a/Classes/DataProcessing/ResponsiveImagesProcessor.php +++ b/Classes/DataProcessing/ResponsiveImagesProcessor.php @@ -23,9 +23,8 @@ * 02110-1301, USA. */ -use Codappix\ResponsiveImages\Configuration\ConfigurationManager; +use Codappix\ResponsiveImages\Domain\Factory\BreakpointFactory; use Codappix\ResponsiveImages\Domain\Factory\RootlineFactory; -use Codappix\ResponsiveImages\Domain\Model\Breakpoint; use TYPO3\CMS\Core\Resource\FileInterface; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface; @@ -42,7 +41,7 @@ final class ResponsiveImagesProcessor implements DataProcessorInterface private array $contentElementSizes = []; public function __construct( - private ConfigurationManager $configurationManager, + private BreakpointFactory $breakpointFactory, private RootlineFactory $rootlineFactory ) { } @@ -105,9 +104,8 @@ private function calculateFileDimensionForBreakpoints(): array { $fileDimensions = []; - $breakpoints = $this->getBreakpoints(); + $breakpoints = $this->breakpointFactory->getByConfigurationPath(['breakpoints']); - /** @var Breakpoint $breakpoint */ foreach ($breakpoints as $breakpoint) { if (isset($this->contentElementSizes[$breakpoint->getIdentifier()]) === false) { continue; @@ -121,19 +119,4 @@ private function calculateFileDimensionForBreakpoints(): array return $fileDimensions; } - - private function getBreakpoints(): array - { - $breakpoints = []; - - $breakpointsByPath = $this->configurationManager->getByPath(['breakpoints']); - - if (is_iterable($breakpointsByPath)) { - foreach ($breakpointsByPath as $breakpointIdentifier => $breakpointData) { - $breakpoints[$breakpointIdentifier] = new Breakpoint($breakpointIdentifier, $breakpointData); - } - } - - return $breakpoints; - } } diff --git a/Classes/Domain/Factory/BreakpointFactory.php b/Classes/Domain/Factory/BreakpointFactory.php new file mode 100644 index 0000000..0256dd6 --- /dev/null +++ b/Classes/Domain/Factory/BreakpointFactory.php @@ -0,0 +1,54 @@ + + * Copyright (C) 2024 Daniel Gohlke + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use Codappix\ResponsiveImages\Configuration\ConfigurationManager; +use Codappix\ResponsiveImages\Domain\Model\Breakpoint; + +final class BreakpointFactory +{ + public function __construct( + private readonly ConfigurationManager $configurationManager + ) { + } + + /** + * @return Breakpoint[] + */ + public function getByConfigurationPath(array|string $configurationPath): array + { + $breakpoints = []; + + $breakpointsByPath = $this->configurationManager->getByPath($configurationPath); + + if (is_iterable($breakpointsByPath)) { + foreach ($breakpointsByPath as $breakpointIdentifier => $breakpointData) { + $breakpoints[$breakpointIdentifier] = new Breakpoint($breakpointIdentifier, $breakpointData); + } + } + + return $breakpoints; + } +} diff --git a/Classes/Domain/Factory/ScalingFactory.php b/Classes/Domain/Factory/ScalingFactory.php index 83ce0c4..c980c62 100644 --- a/Classes/Domain/Factory/ScalingFactory.php +++ b/Classes/Domain/Factory/ScalingFactory.php @@ -30,7 +30,7 @@ final class ScalingFactory { public function __construct( - private ConfigurationManager $configurationManager + private readonly ConfigurationManager $configurationManager ) { } From 0f724440422282be798f556ffe0bf9039697b8bc Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Wed, 10 Apr 2024 20:40:40 +0200 Subject: [PATCH 20/27] CLEANUP: Add license information and some readonly modifier --- .../Configuration/ConfigurationManager.php | 2 +- .../ResponsiveImagesProcessor.php | 4 ++-- Classes/Domain/Factory/BreakpointFactory.php | 1 - Classes/Domain/Factory/RootlineFactory.php | 1 - Classes/Domain/Factory/ScalingFactory.php | 1 - Classes/Domain/Model/Breakpoint.php | 2 +- Classes/Domain/Model/Rootline.php | 1 - Classes/Domain/Model/RootlineElement.php | 2 +- .../Domain/Repository/ContainerRepository.php | 21 ++++++++++++++++++- 9 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Classes/Configuration/ConfigurationManager.php b/Classes/Configuration/ConfigurationManager.php index 449d147..be0b4a6 100644 --- a/Classes/Configuration/ConfigurationManager.php +++ b/Classes/Configuration/ConfigurationManager.php @@ -31,7 +31,7 @@ final class ConfigurationManager { public function __construct( - private array $settings + private readonly array $settings ) { } diff --git a/Classes/DataProcessing/ResponsiveImagesProcessor.php b/Classes/DataProcessing/ResponsiveImagesProcessor.php index 4da1eac..ae45a53 100644 --- a/Classes/DataProcessing/ResponsiveImagesProcessor.php +++ b/Classes/DataProcessing/ResponsiveImagesProcessor.php @@ -41,8 +41,8 @@ final class ResponsiveImagesProcessor implements DataProcessorInterface private array $contentElementSizes = []; public function __construct( - private BreakpointFactory $breakpointFactory, - private RootlineFactory $rootlineFactory + private readonly BreakpointFactory $breakpointFactory, + private readonly RootlineFactory $rootlineFactory ) { } diff --git a/Classes/Domain/Factory/BreakpointFactory.php b/Classes/Domain/Factory/BreakpointFactory.php index 0256dd6..bcd4081 100644 --- a/Classes/Domain/Factory/BreakpointFactory.php +++ b/Classes/Domain/Factory/BreakpointFactory.php @@ -5,7 +5,6 @@ namespace Codappix\ResponsiveImages\Domain\Factory; /* - * Copyright (C) 2024 Justus Moroni * Copyright (C) 2024 Daniel Gohlke * * This program is free software; you can redistribute it and/or diff --git a/Classes/Domain/Factory/RootlineFactory.php b/Classes/Domain/Factory/RootlineFactory.php index 08e7c40..7840a6b 100644 --- a/Classes/Domain/Factory/RootlineFactory.php +++ b/Classes/Domain/Factory/RootlineFactory.php @@ -5,7 +5,6 @@ namespace Codappix\ResponsiveImages\Domain\Factory; /* - * Copyright (C) 2024 Justus Moroni * Copyright (C) 2024 Daniel Gohlke * * This program is free software; you can redistribute it and/or diff --git a/Classes/Domain/Factory/ScalingFactory.php b/Classes/Domain/Factory/ScalingFactory.php index c980c62..d637563 100644 --- a/Classes/Domain/Factory/ScalingFactory.php +++ b/Classes/Domain/Factory/ScalingFactory.php @@ -5,7 +5,6 @@ namespace Codappix\ResponsiveImages\Domain\Factory; /* - * Copyright (C) 2024 Justus Moroni * Copyright (C) 2024 Daniel Gohlke * * This program is free software; you can redistribute it and/or diff --git a/Classes/Domain/Model/Breakpoint.php b/Classes/Domain/Model/Breakpoint.php index e197498..29c143a 100644 --- a/Classes/Domain/Model/Breakpoint.php +++ b/Classes/Domain/Model/Breakpoint.php @@ -31,7 +31,7 @@ final class Breakpoint { public function __construct( private readonly string $identifier, - private array $data + private readonly array $data ) { } diff --git a/Classes/Domain/Model/Rootline.php b/Classes/Domain/Model/Rootline.php index d9e803e..94504b1 100644 --- a/Classes/Domain/Model/Rootline.php +++ b/Classes/Domain/Model/Rootline.php @@ -5,7 +5,6 @@ namespace Codappix\ResponsiveImages\Domain\Model; /* - * Copyright (C) 2024 Justus Moroni * Copyright (C) 2024 Daniel Gohlke * * This program is free software; you can redistribute it and/or diff --git a/Classes/Domain/Model/RootlineElement.php b/Classes/Domain/Model/RootlineElement.php index 1debbe6..99fde2e 100644 --- a/Classes/Domain/Model/RootlineElement.php +++ b/Classes/Domain/Model/RootlineElement.php @@ -37,7 +37,7 @@ public function __construct( private readonly array $data ) { if (isset($data['colPos'])) { - $this->colPos = $data['colPos']; + $this->colPos = (int) $data['colPos']; } } diff --git a/Classes/Domain/Repository/ContainerRepository.php b/Classes/Domain/Repository/ContainerRepository.php index f60666c..3450b4d 100644 --- a/Classes/Domain/Repository/ContainerRepository.php +++ b/Classes/Domain/Repository/ContainerRepository.php @@ -4,13 +4,32 @@ namespace Codappix\ResponsiveImages\Domain\Repository; +/* + * Copyright (C) 2024 Daniel Gohlke + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Error\Exception; class ContainerRepository { public function __construct( - private Connection $connection + private readonly Connection $connection ) { } From e439a1bbad937f0b9d8dd11b99f4aacddcdafbeb Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Wed, 10 Apr 2024 20:45:02 +0200 Subject: [PATCH 21/27] CLEANUP: Add missing return type --- Classes/DataProcessing/ResponsiveImagesProcessor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/DataProcessing/ResponsiveImagesProcessor.php b/Classes/DataProcessing/ResponsiveImagesProcessor.php index ae45a53..6ba78ca 100644 --- a/Classes/DataProcessing/ResponsiveImagesProcessor.php +++ b/Classes/DataProcessing/ResponsiveImagesProcessor.php @@ -51,7 +51,7 @@ public function process( array $contentObjectConfiguration, array $processorConfiguration, array $processedData - ) { + ): array { if (isset($processorConfiguration['if.']) && !$cObj->checkIf($processorConfiguration['if.'])) { return $processedData; } From 616a9f23f9a14aadaf2378d7a7f3b546b7beb574 Mon Sep 17 00:00:00 2001 From: Daniel Gohlke Date: Wed, 10 Apr 2024 20:48:28 +0200 Subject: [PATCH 22/27] CLEANUP: Remove public:true for ConfigurationManager --- Configuration/Services.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index 47946d2..67ea82d 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -30,7 +30,6 @@ services: public: true Codappix\ResponsiveImages\Configuration\ConfigurationManager: - public: true arguments: $settings: '@extbaseSettings.ResponsiveImages' From feaebfb0827004d25ab78777eed26cb6db3c0178 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Thu, 11 Apr 2024 09:19:24 +0200 Subject: [PATCH 23/27] Promote TSFE dependency from RootlineFactory --- Classes/DataProcessing/ResponsiveImagesProcessor.php | 9 ++++++++- Classes/Domain/Factory/RootlineFactory.php | 10 +++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Classes/DataProcessing/ResponsiveImagesProcessor.php b/Classes/DataProcessing/ResponsiveImagesProcessor.php index 6ba78ca..bd1608c 100644 --- a/Classes/DataProcessing/ResponsiveImagesProcessor.php +++ b/Classes/DataProcessing/ResponsiveImagesProcessor.php @@ -25,9 +25,11 @@ use Codappix\ResponsiveImages\Domain\Factory\BreakpointFactory; use Codappix\ResponsiveImages\Domain\Factory\RootlineFactory; +use RuntimeException; use TYPO3\CMS\Core\Resource\FileInterface; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface; +use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; final class ResponsiveImagesProcessor implements DataProcessorInterface { @@ -73,7 +75,12 @@ public function process( return $processedData; } - $rootline = $this->rootlineFactory->create($processedData['data'], $fieldName); + $tsfe = $cObj->getRequest()->getAttribute('frontend.controller'); + if (!$tsfe instanceof TypoScriptFrontendController) { + throw new RuntimeException('Could not fetch TypoScriptFrontendController from request.', 1712819889); + } + + $rootline = $this->rootlineFactory->create($processedData['data'], $fieldName, $tsfe); $this->contentElementSizes = $rootline->getFinalSize(); $this->calculateFileDimensions(); diff --git a/Classes/Domain/Factory/RootlineFactory.php b/Classes/Domain/Factory/RootlineFactory.php index 7840a6b..e5a15b5 100644 --- a/Classes/Domain/Factory/RootlineFactory.php +++ b/Classes/Domain/Factory/RootlineFactory.php @@ -28,6 +28,7 @@ use Codappix\ResponsiveImages\Domain\Model\RootlineElementInterface; use Codappix\ResponsiveImages\Domain\Repository\ContainerRepository; use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; +use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; use TYPO3\CMS\Frontend\Page\PageLayoutResolver; final class RootlineFactory @@ -50,9 +51,10 @@ public function __construct( public function create( array $data, - string $fieldName + string $fieldName, + TypoScriptFrontendController $tsfe ): Rootline { - $this->createBackendLayoutRootlineElement(); + $this->createBackendLayoutRootlineElement($tsfe); $this->determineBackendLayoutColumns(); $this->createContentElementRootlineElement($data, $fieldName); @@ -93,10 +95,8 @@ public function determineBackendLayoutColumns(): void $this->columns = array_map(static fn ($column): int => (int) $column, array_keys($columns)); } - private function createBackendLayoutRootlineElement(): void + private function createBackendLayoutRootlineElement(TypoScriptFrontendController $tsfe): void { - $tsfe = $GLOBALS['TSFE']; - $this->backendLayoutIdentifier = $this->pageLayoutResolver->getLayoutForPage( $tsfe->page, $tsfe->rootLine From 789c8e47d0579017b32983960743e56bfba5fcc9 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Thu, 11 Apr 2024 09:55:36 +0200 Subject: [PATCH 24/27] Prevent potential access to uninitialized property --- Classes/Domain/Model/RootlineElement.php | 4 ++-- Classes/Domain/Model/RootlineElementInterface.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Classes/Domain/Model/RootlineElement.php b/Classes/Domain/Model/RootlineElement.php index 99fde2e..b4a87c4 100644 --- a/Classes/Domain/Model/RootlineElement.php +++ b/Classes/Domain/Model/RootlineElement.php @@ -28,7 +28,7 @@ class RootlineElement implements RootlineElementInterface { - protected int $colPos; + protected ?int $colPos = null; private ?RootlineElementInterface $parent = null; @@ -88,7 +88,7 @@ public function getData(?string $dataIdentifier = null): mixed return $this->data[$dataIdentifier]; } - public function getColPos(): int + public function getColPos(): ?int { return $this->colPos; } diff --git a/Classes/Domain/Model/RootlineElementInterface.php b/Classes/Domain/Model/RootlineElementInterface.php index 7f42274..3f74fc5 100644 --- a/Classes/Domain/Model/RootlineElementInterface.php +++ b/Classes/Domain/Model/RootlineElementInterface.php @@ -34,7 +34,7 @@ public function getScaling(): Scaling; public function getFinalSize(array $multiplier): array; - public function getColPos(): int; + public function getColPos(): ?int; public function getData(?string $dataIdentifier = null): mixed; } From 3d9ba54fa66e410b069598d6773ae8483c3247d0 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Thu, 11 Apr 2024 09:57:00 +0200 Subject: [PATCH 25/27] Mark all classes as final --- Classes/Domain/Factory/RootlineElementFactory.php | 2 +- Classes/Domain/Model/Rootline.php | 2 +- Classes/Domain/Model/RootlineElement.php | 4 ++-- Classes/Domain/Model/Scaling.php | 2 +- Classes/Domain/Repository/ContainerRepository.php | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Classes/Domain/Factory/RootlineElementFactory.php b/Classes/Domain/Factory/RootlineElementFactory.php index cb58e48..e457ee2 100644 --- a/Classes/Domain/Factory/RootlineElementFactory.php +++ b/Classes/Domain/Factory/RootlineElementFactory.php @@ -26,7 +26,7 @@ use Codappix\ResponsiveImages\Domain\Model\RootlineElement; use Codappix\ResponsiveImages\Domain\Model\RootlineElementInterface; -class RootlineElementFactory +final class RootlineElementFactory { public function __construct( private readonly ScalingFactory $scalingFactory diff --git a/Classes/Domain/Model/Rootline.php b/Classes/Domain/Model/Rootline.php index 94504b1..f2d4b6e 100644 --- a/Classes/Domain/Model/Rootline.php +++ b/Classes/Domain/Model/Rootline.php @@ -23,7 +23,7 @@ * 02110-1301, USA. */ -class Rootline implements RootlineInterface +final class Rootline implements RootlineInterface { public function __construct( private readonly RootlineElementInterface $rootlineElement diff --git a/Classes/Domain/Model/RootlineElement.php b/Classes/Domain/Model/RootlineElement.php index b4a87c4..e9a16f9 100644 --- a/Classes/Domain/Model/RootlineElement.php +++ b/Classes/Domain/Model/RootlineElement.php @@ -26,9 +26,9 @@ use Exception; -class RootlineElement implements RootlineElementInterface +final class RootlineElement implements RootlineElementInterface { - protected ?int $colPos = null; + private ?int $colPos = null; private ?RootlineElementInterface $parent = null; diff --git a/Classes/Domain/Model/Scaling.php b/Classes/Domain/Model/Scaling.php index 27b9feb..545b237 100644 --- a/Classes/Domain/Model/Scaling.php +++ b/Classes/Domain/Model/Scaling.php @@ -23,7 +23,7 @@ * 02110-1301, USA. */ -class Scaling +final class Scaling { /** * @var float[] diff --git a/Classes/Domain/Repository/ContainerRepository.php b/Classes/Domain/Repository/ContainerRepository.php index 3450b4d..ae05e17 100644 --- a/Classes/Domain/Repository/ContainerRepository.php +++ b/Classes/Domain/Repository/ContainerRepository.php @@ -26,7 +26,7 @@ use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Error\Exception; -class ContainerRepository +final class ContainerRepository { public function __construct( private readonly Connection $connection From 6669cc28f724726211ba5c49a917242f15410196 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Thu, 11 Apr 2024 09:57:54 +0200 Subject: [PATCH 26/27] Make all methods private --- Classes/Domain/Model/RootlineElement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Domain/Model/RootlineElement.php b/Classes/Domain/Model/RootlineElement.php index e9a16f9..be23c68 100644 --- a/Classes/Domain/Model/RootlineElement.php +++ b/Classes/Domain/Model/RootlineElement.php @@ -93,7 +93,7 @@ public function getColPos(): ?int return $this->colPos; } - protected function multiplyArray(array $factor1, array $factor2): array + private function multiplyArray(array $factor1, array $factor2): array { if (empty($factor1)) { return $factor2; From b58ceaf2ba4a364a0ef438e9a82abc9e7b362059 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Thu, 11 Apr 2024 10:02:55 +0200 Subject: [PATCH 27/27] Shorten array map for casting to use existing native function --- Classes/Domain/Factory/RootlineFactory.php | 2 +- Classes/Domain/Model/Scaling.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Classes/Domain/Factory/RootlineFactory.php b/Classes/Domain/Factory/RootlineFactory.php index e5a15b5..b954ad5 100644 --- a/Classes/Domain/Factory/RootlineFactory.php +++ b/Classes/Domain/Factory/RootlineFactory.php @@ -92,7 +92,7 @@ public function determineBackendLayoutColumns(): void ); assert(is_array($columns)); - $this->columns = array_map(static fn ($column): int => (int) $column, array_keys($columns)); + $this->columns = array_map('intval', array_keys($columns)); } private function createBackendLayoutRootlineElement(TypoScriptFrontendController $tsfe): void diff --git a/Classes/Domain/Model/Scaling.php b/Classes/Domain/Model/Scaling.php index 545b237..d4a5ed2 100644 --- a/Classes/Domain/Model/Scaling.php +++ b/Classes/Domain/Model/Scaling.php @@ -38,11 +38,11 @@ final class Scaling public function __construct(array $multiplier, array $sizes) { if (!empty($multiplier)) { - $this->multiplier = array_map(static fn ($multiplier): float => (float) $multiplier, $multiplier); + $this->multiplier = array_map('floatval', $multiplier); } if (!empty($sizes)) { - $this->sizes = array_map(static fn ($size): int => (int) $size, $sizes); + $this->sizes = array_map('intval', $sizes); } }