Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TASK: Allow sizes and multiplier for container #26

Merged
merged 27 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
da76dcd
TASK: Allow sizes and multiplier for container
d-g-codappix Apr 4, 2024
472aff8
Cleanup: Reduce complexity of getSizesAndMultiplierFromRootline()
d-g-codappix Apr 4, 2024
412b71b
CLEANUP: Move $multiplier and $sizes to ScalungConfiguration Object
d-g-codappix Apr 5, 2024
619996b
CLEANUP: Remove extra variable for readConfigurationByPath
d-g-codappix Apr 5, 2024
f3adfbf
CLEANUP: Remove superfluous $size parameter from method
d-g-codappix Apr 5, 2024
d0983e1
TASK: Refactor rootline handling
d-g-codappix Apr 5, 2024
ebe1c0c
CLEANUP: Use DI for ContainerRepository
d-g-codappix Apr 9, 2024
d4402c1
CLEANUP: Limit selected columns in ContainerRepository
d-g-codappix Apr 9, 2024
a4637ca
CLEANUP: Remove unused old method
d-g-codappix Apr 9, 2024
01dea4c
CLEANUP: Mark intended as abstract class as abstact
d-g-codappix Apr 9, 2024
e789370
CLEANUP: Initialize $parent with null
d-g-codappix Apr 9, 2024
dd182a8
CLEANUP: Remove double initialization
d-g-codappix Apr 9, 2024
7d5e597
CLEANUP: Make Rootline class a factory
d-g-codappix Apr 9, 2024
ba47a7a
CLEANUP: Move new rootline element creation to factories
d-g-codappix Apr 9, 2024
78585e7
CLEANUP: Use determineContainerColumn only one time
d-g-codappix Apr 10, 2024
b9e0161
CLEANUP: Use arrays for retrieving information from configuration
d-g-codappix Apr 10, 2024
83b04a3
CLEANUP: Replace BackendLayout with exiting RootlineElement
d-g-codappix Apr 10, 2024
3dc622c
CLEANUP: Move Breakpoint to Domain/Model folder
d-g-codappix Apr 10, 2024
931c6bf
CLEANUP: Create Breakpoints in BreakpointFactory
d-g-codappix Apr 10, 2024
0f72444
CLEANUP: Add license information and some readonly modifier
d-g-codappix Apr 10, 2024
e439a1b
CLEANUP: Add missing return type
d-g-codappix Apr 10, 2024
616a9f2
CLEANUP: Remove public:true for ConfigurationManager
d-g-codappix Apr 10, 2024
feaebfb
Promote TSFE dependency from RootlineFactory
DanielSiepmann Apr 11, 2024
789c8e4
Prevent potential access to uninitialized property
DanielSiepmann Apr 11, 2024
3d9ba54
Mark all classes as final
DanielSiepmann Apr 11, 2024
6669cc2
Make all methods private
DanielSiepmann Apr 11, 2024
b58ceaf
Shorten array map for casting to use existing native function
DanielSiepmann Apr 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Classes/Configuration/ConfigurationManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
final class ConfigurationManager
{
public function __construct(
private array $settings
private readonly array $settings
) {
}

Expand All @@ -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);
}
}
45 changes: 17 additions & 28 deletions Classes/DataProcessing/ResponsiveImagesProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,16 @@
* 02110-1301, USA.
*/

use Codappix\ResponsiveImages\Configuration\ConfigurationManager;
use Codappix\ResponsiveImages\Sizes\Breakpoint;
use Codappix\ResponsiveImages\Sizes\Rootline;
use Codappix\ResponsiveImages\Domain\Factory\BreakpointFactory;
use Codappix\ResponsiveImages\Domain\Factory\RootlineFactory;
use RuntimeException;
use TYPO3\CMS\Core\Resource\FileInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;

final class ResponsiveImagesProcessor implements DataProcessorInterface
{
private readonly ConfigurationManager $configurationManager;

/**
* @var FileInterface[]
*/
Expand All @@ -44,17 +42,18 @@ final class ResponsiveImagesProcessor implements DataProcessorInterface

private array $contentElementSizes = [];

public function __construct()
{
$this->configurationManager = GeneralUtility::makeInstance(ConfigurationManager::class);
public function __construct(
private readonly BreakpointFactory $breakpointFactory,
private readonly RootlineFactory $rootlineFactory
) {
}

public function process(
ContentObjectRenderer $cObj,
array $contentObjectConfiguration,
array $processorConfiguration,
array $processedData
) {
): array {
if (isset($processorConfiguration['if.']) && !$cObj->checkIf($processorConfiguration['if.'])) {
return $processedData;
}
Expand All @@ -76,7 +75,13 @@ public function process(
return $processedData;
}

$this->contentElementSizes = (new Rootline($processedData['data'], $fieldName))->getFinalSizes();
$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();

$targetFieldName = (string) $cObj->stdWrapValue(
Expand Down Expand Up @@ -106,9 +111,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;
Expand All @@ -122,19 +126,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;
}
}
53 changes: 53 additions & 0 deletions Classes/Domain/Factory/BreakpointFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace Codappix\ResponsiveImages\Domain\Factory;

/*
* Copyright (C) 2024 Daniel Gohlke <[email protected]>
*
* 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;
}
}
42 changes: 42 additions & 0 deletions Classes/Domain/Factory/RootlineElementFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace Codappix\ResponsiveImages\Domain\Factory;

/*
* Copyright (C) 2024 Daniel Gohlke <[email protected]>
*
* 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\Domain\Model\RootlineElement;
use Codappix\ResponsiveImages\Domain\Model\RootlineElementInterface;

final class RootlineElementFactory
{
public function __construct(
private readonly ScalingFactory $scalingFactory
) {
}

public function create(array $data, array|string $configurationPath): RootlineElementInterface
{
$scaling = $this->scalingFactory->getByConfigurationPath($configurationPath);

return new RootlineElement($scaling, $data);
}
}
182 changes: 182 additions & 0 deletions Classes/Domain/Factory/RootlineFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
<?php

declare(strict_types=1);

namespace Codappix\ResponsiveImages\Domain\Factory;

/*
* Copyright (C) 2024 Daniel Gohlke <[email protected]>
*
* 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\Rootline;
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
{
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 RootlineElementFactory $rootlineElementFactory
) {
}

public function create(
array $data,
string $fieldName,
TypoScriptFrontendController $tsfe
): Rootline {
$this->createBackendLayoutRootlineElement($tsfe);
$this->determineBackendLayoutColumns();

$this->createContentElementRootlineElement($data, $fieldName);
$this->determineRootline($this->contentElement);

return new Rootline($this->contentElement);
}

public function createContainerColumnRootlineElement(
array $data,
RootlineElementInterface $contentElement
): RootlineElementInterface {
$newContainerColumn = $this->rootlineElementFactory->create(
$data,
[
'container',
$data['CType'],
'columns',
(string) $contentElement->getColPos(),
]
);
$contentElement->setParent($newContainerColumn);

return $newContainerColumn;
}

public function determineBackendLayoutColumns(): void
{
$columns = $this->configurationManager->getByPath(
[
'backendlayouts',
$this->backendLayoutIdentifier,
'columns',
]
);

assert(is_array($columns));
$this->columns = array_map('intval', array_keys($columns));
}

private function createBackendLayoutRootlineElement(TypoScriptFrontendController $tsfe): void
{
$this->backendLayoutIdentifier = $this->pageLayoutResolver->getLayoutForPage(
$tsfe->page,
$tsfe->rootLine
);

$this->backendLayout = $this->rootlineElementFactory->create(
[],
[
'backendlayouts',
$this->backendLayoutIdentifier,
]
);
}

private function createBackendLayoutColumnRootlineElement(RootlineElementInterface $contentElement): void
{
$newBackendLayoutColumn = $this->rootlineElementFactory->create(
[],
[
'backendlayouts',
$this->backendLayoutIdentifier,
'columns',
(string) $contentElement->getColPos(),
]
);

$newBackendLayoutColumn->setParent($this->backendLayout);
$contentElement->setParent($newBackendLayoutColumn);
}

private function createContainerRootlineElement(
array $data,
RootlineElementInterface $contentElement
): RootlineElementInterface {
$newContainerColumn = $this->createContainerColumnRootlineElement($data, $contentElement);

$newContainer = $this->rootlineElementFactory->create(
$data,
[
'container',
$data['CType'],
]
);
$newContainerColumn->setParent($newContainer);

return $newContainer;
}

private function createContentElementRootlineElement(
array $data,
string $fieldName
): void {
$this->contentElement = $this->rootlineElementFactory->create(
$data,
[
'contentelements',
$data['CType'],
$fieldName,
]
);
}

private function determineRootline(RootlineElementInterface $contentElement): void
{
if (in_array($contentElement->getColPos(), $this->columns, true)) {
$this->createBackendLayoutColumnRootlineElement($contentElement);

return;
}

if (ExtensionManagementUtility::isLoaded('b13/container')) {
$parentContainer = $contentElement->getData('tx_container_parent');
assert(is_int($parentContainer));

$parent = $this->createContainerRootlineElement(
$this->containerRepository->findByIdentifier($parentContainer),
$contentElement
);

$this->determineRootline($parent);
}
}
}
Loading