Skip to content

Commit

Permalink
Simplify data mapper with unlocalized and localized dimension content (
Browse files Browse the repository at this point in the history
…#205)

* Simplify data maper with unlocalized and localized dimension content

* Update Author, Excerpt, SeoData, Template Mapper Tests

* Update some datamapper and tests

* Throw exception when no route mapping is found

* Apply suggestions from code review

Co-authored-by: nnatter <niklas.natter@gmail.com>

* Optimize title handling

* Update CreateExampleTrait

* Update

Co-authored-by: nnatter <niklas.natter@gmail.com>
  • Loading branch information
alexander-schranz and niklasnatter committed Oct 8, 2021
1 parent 9fa38cb commit 58ca022
Show file tree
Hide file tree
Showing 27 changed files with 1,022 additions and 1,683 deletions.
18 changes: 15 additions & 3 deletions Content/Application/ContentDataMapper/ContentDataMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,23 @@ public function __construct(iterable $dataMappers)
}

public function map(
array $data,
DimensionContentCollectionInterface $dimensionContentCollection
DimensionContentCollectionInterface $dimensionContentCollection,
array $dimensionAttributes,
array $data
): void {
$localizedDimensionAttributes = $dimensionAttributes;
$unlocalizedDimensionAttributes = $dimensionAttributes;
$unlocalizedDimensionAttributes['locale'] = null;
$unlocalizedDimensionContent = $dimensionContentCollection->getDimensionContent($unlocalizedDimensionAttributes);
$localizedDimensionContent = $dimensionContentCollection->getDimensionContent($localizedDimensionAttributes);

if (!$unlocalizedDimensionContent || !$localizedDimensionContent) {
// TODO see https://github.com/sulu/SuluContentBundle/pull/204
throw new \RuntimeException('Create unlocalized and localized dimension content.');
}

foreach ($this->dataMappers as $mapper) {
$mapper->map($data, $dimensionContentCollection);
$mapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ interface ContentDataMapperInterface
{
/**
* @param array<string, mixed> $data
* @param mixed[] $dimensionAttributes
*/
public function map(
array $data,
DimensionContentCollectionInterface $dimensionContentCollection
DimensionContentCollectionInterface $dimensionContentCollection,
array $dimensionAttributes,
array $data
): void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

use Sulu\Bundle\ContentBundle\Content\Domain\Factory\ContactFactoryInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\AuthorInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface;

class AuthorDataMapper implements DataMapperInterface
{
Expand All @@ -30,42 +30,27 @@ public function __construct(ContactFactoryInterface $contactFactory)
}

public function map(
array $data,
DimensionContentCollectionInterface $dimensionContentCollection
DimensionContentInterface $unlocalizedDimensionContent,
DimensionContentInterface $localizedDimensionContent,
array $data
): void {
$dimensionAttributes = $dimensionContentCollection->getDimensionAttributes();
$unlocalizedDimensionAttributes = \array_merge($dimensionAttributes, ['locale' => null]);
$unlocalizedObject = $dimensionContentCollection->getDimensionContent($unlocalizedDimensionAttributes);

if (!$unlocalizedObject instanceof AuthorInterface) {
return;
}

$localizedObject = $dimensionContentCollection->getDimensionContent($dimensionAttributes);

if ($localizedObject) {
if (!$localizedObject instanceof AuthorInterface) {
throw new \RuntimeException(\sprintf('Expected "$localizedObject" from type "%s" but "%s" given.', AuthorInterface::class, \get_class($localizedObject)));
}

$this->setAuthorData($localizedObject, $data);

if (!$localizedDimensionContent instanceof AuthorInterface) {
return;
}

$this->setAuthorData($unlocalizedObject, $data);
$this->setAuthorData($localizedDimensionContent, $data);
}

/**
* @param mixed[] $data
*/
private function setAuthorData(AuthorInterface $dimensionContent, array $data): void
{
if (isset($data['author'])) {
if (\array_key_exists('author', $data)) {
$dimensionContent->setAuthor($this->contactFactory->create($data['author']));
}

if (isset($data['authored'])) {
if (\array_key_exists('authored', $data)) {
$dimensionContent->setAuthored(new \DateTimeImmutable($data['authored']));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@

namespace Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper;

use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface;

interface DataMapperInterface
{
/**
* @param array<string, mixed> $data
*/
public function map(
array $data,
DimensionContentCollectionInterface $dimensionContentCollection
DimensionContentInterface $unlocalizedDimensionContent,
DimensionContentInterface $localizedDimensionContent,
array $data
): void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

use Sulu\Bundle\ContentBundle\Content\Domain\Factory\CategoryFactoryInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Factory\TagFactoryInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\ExcerptInterface;

class ExcerptDataMapper implements DataMapperInterface
Expand All @@ -37,45 +37,44 @@ public function __construct(TagFactoryInterface $tagFactory, CategoryFactoryInte
}

public function map(
array $data,
DimensionContentCollectionInterface $dimensionContentCollection
DimensionContentInterface $unlocalizedDimensionContent,
DimensionContentInterface $localizedDimensionContent,
array $data
): void {
$dimensionAttributes = $dimensionContentCollection->getDimensionAttributes();
$unlocalizedDimensionAttributes = \array_merge($dimensionAttributes, ['locale' => null]);
$unlocalizedObject = $dimensionContentCollection->getDimensionContent($unlocalizedDimensionAttributes);

if (!$unlocalizedObject instanceof ExcerptInterface) {
return;
}

$localizedObject = $dimensionContentCollection->getDimensionContent($dimensionAttributes);

if ($localizedObject) {
if (!$localizedObject instanceof ExcerptInterface) {
throw new \RuntimeException(\sprintf('Expected "$localizedObject" from type "%s" but "%s" given.', ExcerptInterface::class, \get_class($localizedObject)));
}

$this->setExcerptData($localizedObject, $data);

if (!$localizedDimensionContent instanceof ExcerptInterface) {
return;
}

$this->setExcerptData($unlocalizedObject, $data);
$this->setExcerptData($localizedDimensionContent, $data);
}

/**
* @param mixed[] $data
*/
private function setExcerptData(ExcerptInterface $dimensionContent, array $data): void
{
$dimensionContent->setExcerptTitle($data['excerptTitle'] ?? null);
$dimensionContent->setExcerptDescription($data['excerptDescription'] ?? null);
$dimensionContent->setExcerptMore($data['excerptMore'] ?? null);
$dimensionContent->setExcerptImage($data['excerptImage'] ?? null);
$dimensionContent->setExcerptIcon($data['excerptIcon'] ?? null);
$dimensionContent->setExcerptTags($this->tagFactory->create($data['excerptTags'] ?? []));
$dimensionContent->setExcerptCategories(
$this->categoryFactory->create($data['excerptCategories'] ?? [])
);
if (\array_key_exists('excerptTitle', $data)) {
$dimensionContent->setExcerptTitle($data['excerptTitle']);
}
if (\array_key_exists('excerptDescription', $data)) {
$dimensionContent->setExcerptDescription($data['excerptDescription']);
}
if (\array_key_exists('excerptMore', $data)) {
$dimensionContent->setExcerptMore($data['excerptMore']);
}
if (\array_key_exists('excerptImage', $data)) {
$dimensionContent->setExcerptImage($data['excerptImage']);
}
if (\array_key_exists('excerptIcon', $data)) {
$dimensionContent->setExcerptIcon($data['excerptIcon']);
}
if (\array_key_exists('excerptTags', $data)) {
$dimensionContent->setExcerptTags($this->tagFactory->create($data['excerptTags'] ?: []));
}
if (\array_key_exists('excerptCategories', $data)) {
$dimensionContent->setExcerptCategories(
$this->categoryFactory->create($data['excerptCategories'] ?: [])
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@

namespace Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper;

use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\RoutableInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\TemplateInterface;
use Sulu\Bundle\RouteBundle\Generator\RouteGeneratorInterface;
use Sulu\Bundle\RouteBundle\Manager\ConflictResolverInterface;
use Sulu\Bundle\RouteBundle\Manager\RouteManagerInterface;
use Sulu\Component\Content\Metadata\Factory\StructureMetadataFactoryInterface;
use Sulu\Component\Content\Metadata\PropertyMetadata;
Expand All @@ -40,11 +39,6 @@ class RoutableDataMapper implements DataMapperInterface
*/
private $routeManager;

/**
* @var ConflictResolverInterface
*/
private $conflictResolver;

/**
* @var array<string, string>
*/
Expand All @@ -63,37 +57,34 @@ public function __construct(
StructureMetadataFactoryInterface $factory,
RouteGeneratorInterface $routeGenerator,
RouteManagerInterface $routeManager,
ConflictResolverInterface $conflictResolver,
array $structureDefaultTypes,
array $routeMappings
) {
$this->factory = $factory;
$this->routeGenerator = $routeGenerator;
$this->routeManager = $routeManager;
$this->conflictResolver = $conflictResolver;
$this->structureDefaultTypes = $structureDefaultTypes;
$this->routeMappings = $routeMappings;
}

public function map(
array $data,
DimensionContentCollectionInterface $dimensionContentCollection
DimensionContentInterface $unlocalizedDimensionContent,
DimensionContentInterface $localizedDimensionContent,
array $data
): void {
$dimensionAttributes = $dimensionContentCollection->getDimensionAttributes();
$localizedObject = $dimensionContentCollection->getDimensionContent($dimensionAttributes);

$unlocalizedDimensionAttributes = \array_merge($dimensionAttributes, ['locale' => null]);
$unlocalizedObject = $dimensionContentCollection->getDimensionContent($unlocalizedDimensionAttributes);

if (!$localizedObject || !$localizedObject instanceof RoutableInterface) {
if (!$localizedDimensionContent instanceof RoutableInterface) {
return;
}

if (!$localizedObject instanceof TemplateInterface) {
throw new \RuntimeException('LocalizedObject needs to extend the TemplateInterface');
if (!$localizedDimensionContent instanceof TemplateInterface) {
throw new \RuntimeException('LocalizedDimensionContent needs to extend the TemplateInterface.');
}

$type = $localizedObject::getTemplateType();
if (DimensionContentInterface::STAGE_LIVE !== $localizedDimensionContent->getStage()) {
// return;
}

$type = $localizedDimensionContent::getTemplateType();

/** @var string|null $template */
$template = $data['template'] ?? null;
Expand All @@ -112,32 +103,28 @@ public function map(
}

$property = $this->getRouteProperty($metadata);
if (!$property) {
return;
}

if (!$localizedObject->getResourceId()) {
// FIXME the code only works if the entity is flushed once and has a valid id

if (!$property) {
return;
}

$locale = $localizedObject->getLocale();
$locale = $localizedDimensionContent->getLocale();
if (!$locale) {
return;
throw new \RuntimeException('Expected a LocalizedDimensionContent with a locale.');
}

/** @var string $name */
$name = $property->getName();

$currentRoutePath = $localizedObject->getTemplateData()[$name] ?? null;
$currentRoutePath = $localizedDimensionContent->getTemplateData()[$name] ?? null;
if (!\array_key_exists($name, $data) && null !== $currentRoutePath) {
return;
}

$entityClass = null;
$routeSchema = null;
$resourceKey = $localizedObject::getResourceKey();
$resourceKey = $localizedDimensionContent::getResourceKey();

foreach ($this->routeMappings as $key => $mapping) {
if ($resourceKey === $mapping['resource_key']) {
$entityClass = $mapping['entityClass'] ?? $key;
Expand All @@ -147,45 +134,55 @@ public function map(
}

if (null === $entityClass || null === $routeSchema) {
// TODO FIXME add test case for this
return; // @codeCoverageIgnore
throw new \RuntimeException(\sprintf('No route mapping found for "%s".', $resourceKey));
}

$routePath = $data[$name] ?? null;

if (!$routePath) {
/** @var mixed $routeGenerationData */
$routeGenerationData = \array_merge(
$data,
[
'_unlocalizedObject' => $unlocalizedObject,
'_localizedObject' => $localizedObject,
'_unlocalizedObject' => $unlocalizedDimensionContent,
'_localizedObject' => $localizedDimensionContent,
]
);

$routePath = $this->routeGenerator->generate(
$routeGenerationData,
$routeSchema
);
}

if ('/' === $routePath) {
return;
}
if ('/' === $routePath) {
throw new \RuntimeException('Not allowed url "/" given or generated.');
}

$route = $this->routeManager->createOrUpdateByAttributes(
$entityClass,
(string) $localizedObject->getResourceId(),
$locale,
$routePath
);
if (DimensionContentInterface::STAGE_LIVE === $localizedDimensionContent->getStage()) {
if (!$localizedDimensionContent->getResourceId()) {
// TODO route bundle should work to update the entity later with a resourceId over UPDATE SQL statement
throw new \RuntimeException('Expected a LocalizedDimensionContent with a resourceId.');
}

$this->conflictResolver->resolve($route);
// route should only be updated in live dimension
$route = $this->routeManager->createOrUpdateByAttributes(
$entityClass,
(string) $localizedDimensionContent->getResourceId(),
$locale,
$routePath,
true
);

$routePath = $route->getPath();
}

if (($data[$name] ?? null) !== $route->getPath()) {
$localizedObject->setTemplateData(
$oldData = $localizedDimensionContent->getTemplateData();
if (($oldData[$name] ?? null) !== $routePath) {
$localizedDimensionContent->setTemplateData(
\array_merge(
$localizedObject->getTemplateData(),
[$name => $route->getPath()]
$oldData,
[$name => $routePath]
)
);
}
Expand Down

0 comments on commit 58ca022

Please sign in to comment.