Skip to content

Commit

Permalink
add routable-interface
Browse files Browse the repository at this point in the history
  • Loading branch information
wachterjohannes committed Nov 15, 2019
1 parent a43e8fa commit ac59461
Show file tree
Hide file tree
Showing 28 changed files with 1,901 additions and 7 deletions.
121 changes: 121 additions & 0 deletions Content/Application/ContentDimensionFactory/Mapper/RouteMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?php

declare(strict_types=1);

/*
* This file is part of Sulu.
*
* (c) Sulu GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\ContentBundle\Content\Application\ContentDimensionFactory\Mapper;

use Sulu\Bundle\ContentBundle\Content\Domain\Model\ContentDimensionInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\RoutableInterface;
use Sulu\Bundle\RouteBundle\Generator\RouteGeneratorInterface;
use Sulu\Bundle\RouteBundle\Manager\RouteManagerInterface;
use Sulu\Component\Content\Metadata\Factory\StructureMetadataFactoryInterface;
use Sulu\Component\Content\Metadata\PropertyMetadata;
use Sulu\Component\Content\Metadata\StructureMetadata;

class RouteMapper implements MapperInterface
{
/**
* @var StructureMetadataFactoryInterface
*/
private $factory;

/**
* @var RouteGeneratorInterface
*/
private $routeGenerator;

/**
* @var RouteManagerInterface
*/
private $routeManager;

public function __construct(
StructureMetadataFactoryInterface $factory,
RouteGeneratorInterface $routeGenerator,
RouteManagerInterface $routeManager
) {
$this->factory = $factory;
$this->routeGenerator = $routeGenerator;
$this->routeManager = $routeManager;
}

public function map(
array $data,
object $contentDimension,
?object $localizedContentDimension = null
): void {
if (!$localizedContentDimension || !$localizedContentDimension instanceof RoutableInterface || !$localizedContentDimension instanceof ContentDimensionInterface) {
return;
}

if (!isset($data['template'])) {
throw new \RuntimeException('Expected "template" to be set in the data array.');
}

$template = $data['template'];
$type = $localizedContentDimension->getTemplateType();

$metadata = $this->factory->getStructureMetadata($type, $template);
if (!$metadata) {
return;
}

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

if (!$localizedContentDimension->getContentId()) {
// FIXME the code only works if the content-dimension is flushed once and has a valid id

return;
}

$locale = $localizedContentDimension->getDimension()->getLocale();
if (!$locale) {
return;
}

$routePath = $data[$property->getName()] ?? null;
if (!$routePath) {
$routePath = $this->routeGenerator->generate(
$localizedContentDimension,
['route_schema' => '/{object.getTitle()}']
);

$localizedContentDimension->setTemplateData(
array_merge(
$localizedContentDimension->getTemplateData(),
[$property->getName() => $routePath]
)
);
}

$this->routeManager->createOrUpdateByAttributes(
$localizedContentDimension->getContentClass(),
(string) $localizedContentDimension->getContentId(),
$locale,
$routePath
);
}

private function getRouteProperty(StructureMetadata $metadata): ?PropertyMetadata
{
foreach ($metadata->getProperties() as $property) {
if ('route' === $property->getType()) {
return $property;
}
}

return null;
}
}
51 changes: 51 additions & 0 deletions Content/Application/Message/LoadContentViewMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

/*
* This file is part of Sulu.
*
* (c) Sulu GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\ContentBundle\Content\Application\Message;

use Sulu\Bundle\ContentBundle\Content\Domain\Model\ContentInterface;

class LoadContentViewMessage
{
/**
* @var ContentInterface
*/
private $content;

/**
* @var mixed[]
*/
private $dimensionAttributes;

/**
* @param mixed[] $dimensionAttributes
*/
public function __construct(ContentInterface $content, array $dimensionAttributes)
{
$this->content = $content;
$this->dimensionAttributes = $dimensionAttributes;
}

public function getContent(): ContentInterface
{
return $this->content;
}

/**
* @return mixed[]
*/
public function getDimensionAttributes(): array
{
return $this->dimensionAttributes;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

/*
* This file is part of Sulu.
*
* (c) Sulu GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\ContentBundle\Content\Application\MessageHandler;

use Sulu\Bundle\ContentBundle\Content\Application\ContentDimensionLoader\ContentDimensionLoaderInterface;
use Sulu\Bundle\ContentBundle\Content\Application\Message\LoadContentViewMessage;
use Sulu\Bundle\ContentBundle\Content\Domain\Factory\ViewFactoryInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\ContentViewInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Repository\DimensionRepositoryInterface;

class LoadContentViewMessageHandler
{
/**
* @var DimensionRepositoryInterface
*/
private $dimensionRepository;

/**
* @var ContentDimensionLoaderInterface
*/
private $contentDimensionLoader;

/**
* @var ViewFactoryInterface
*/
private $viewFactory;

public function __construct(
DimensionRepositoryInterface $dimensionRepository,
ContentDimensionLoaderInterface $contentDimensionLoader,
ViewFactoryInterface $viewFactory
) {
$this->dimensionRepository = $dimensionRepository;
$this->contentDimensionLoader = $contentDimensionLoader;
$this->viewFactory = $viewFactory;
}

public function __invoke(LoadContentViewMessage $message): ContentViewInterface
{
$content = $message->getContent();
$dimensionCollection = $this->dimensionRepository->findByAttributes($message->getDimensionAttributes());
$contentDimensionCollection = $this->contentDimensionLoader->load($content, $dimensionCollection);

return $this->viewFactory->create($contentDimensionCollection);
}
}
2 changes: 2 additions & 0 deletions Content/Domain/Model/ContentInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ interface ContentInterface
{
public static function getResourceKey(): string;

public function getId();

/**
* @return Collection<ContentDimensionInterface>
*/
Expand Down
27 changes: 27 additions & 0 deletions Content/Domain/Model/RoutableInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

/*
* This file is part of Sulu.
*
* (c) Sulu GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\ContentBundle\Content\Domain\Model;

/**
* Marker interface for autoloading the doctrine metadata for routables.
*/
interface RoutableInterface extends TemplateInterface
{
public function getContentClass(): string;

/**
* @return mixed
*/
public function getContentId();
}
10 changes: 7 additions & 3 deletions Content/Infrastructure/Doctrine/ContentDimensionLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,21 @@ public function load(
DimensionCollectionInterface $collection
): ContentDimensionCollectionInterface {
$classMetadata = $this->entityManager->getClassMetadata(\get_class($content));
$contentDimensionClass = $classMetadata->getAssociationMapping('dimensions')['targetEntity'];
$associationMapping = $classMetadata->getAssociationMapping('dimensions');
$contentDimensionClass = $associationMapping['targetEntity'];

$queryBuilder = $this->entityManager->createQueryBuilder()
->from($contentDimensionClass, 'contentDimension')
->select('contentDimension')
->addSelect('dimension')
->innerJoin('contentDimension.dimension', 'dimension');
->innerJoin('contentDimension.dimension', 'dimension')
->innerJoin('contentDimension.' . $associationMapping['mappedBy'], 'content')
->where('content.id = :id')
->setParameter('id', $content->getId());

$dimensionIds = $collection->getDimensionIds();

$queryBuilder->where($queryBuilder->expr()->in('dimension.id', $dimensionIds));
$queryBuilder->andWhere($queryBuilder->expr()->in('dimension.id', $dimensionIds));

/** @var ContentDimensionInterface[] $contentDimensions */
$contentDimensions = [];
Expand Down
Loading

0 comments on commit ac59461

Please sign in to comment.