Skip to content

Commit

Permalink
TASK: Allow sizes and multiplier for container (#26)
Browse files Browse the repository at this point in the history
* Daniel Siepmann couldn't resist to miss use this review to refactor
the architecture.

Related: #22

---------

Co-authored-by: Daniel Gohlke <[email protected]>
Co-authored-by: Daniel Siepmann <[email protected]>
  • Loading branch information
3 people authored Apr 11, 2024
1 parent b72561d commit 694f7a8
Show file tree
Hide file tree
Showing 33 changed files with 998 additions and 665 deletions.
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

0 comments on commit 694f7a8

Please sign in to comment.