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 14, 2019
1 parent a43e8fa commit 9c7b9df
Show file tree
Hide file tree
Showing 19 changed files with 1,157 additions and 4 deletions.
111 changes: 111 additions & 0 deletions Content/Application/ContentDimensionFactory/Mapper/RouteMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?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\ContentBundle\Content\Domain\Repository\DimensionRepositoryInterface;
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 DimensionRepositoryInterface
*/
private $dimensionRepository;

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

public function __construct(
StructureMetadataFactoryInterface $factory,
DimensionRepositoryInterface $dimensionRepository,
RouteManagerInterface $routeManager
) {
$this->factory = $factory;
$this->dimensionRepository = $dimensionRepository;
$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;
}

/** @var string $routePath */
$routePath = $data[$property->getName()] ?? null;
$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);
}
}
24 changes: 24 additions & 0 deletions Content/Domain/Model/RoutableInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?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;

public function getContentId(): ?int;
}
125 changes: 125 additions & 0 deletions Content/Infrastructure/Sulu/Route/ContentDocument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?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\Infrastructure\Sulu\Route;

use Sulu\Bundle\ContentBundle\Content\Domain\Model\ExcerptInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\SeoInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\TemplateInterface;
use Sulu\Component\Content\Document\Behavior\ExtensionBehavior;

class ContentDocument implements ExtensionBehavior
{
/**
* @var TemplateInterface
*/
private $content;

/**
* @var string
*/
private $locale;

public function __construct(TemplateInterface $content, string $locale)
{
$this->content = $content;
$this->locale = $locale;
}

public function getExtensionsData()
{
$seo = [];
if ($this->content instanceof SeoInterface) {
$seo = [
'title' => $this->content->getSeoTitle(),
'description' => $this->content->getSeoDescription(),
'keywords' => $this->content->getSeoKeywords(),
'canonicalUrl' => $this->content->getSeoCanonicalUrl(),
'noIndex' => $this->content->getSeoNoIndex(),
'noFollow' => $this->content->getSeoNoFollow(),
'hideInSitemap' => $this->content->getSeoHideInSitemap(),
];
}

$excerpt = [];
if ($this->content instanceof ExcerptInterface) {
$excerpt = [
'title' => $this->content->getExcerptTitle(),
'description' => $this->content->getExcerptDescription(),
'more' => $this->content->getExcerptMore(),
'categories' => $this->content->getExcerptCategoryIds(),
'tags' => $this->content->getExcerptTags(),
];
}

return [
'seo' => $seo,
'excerpt' => $excerpt,
];
}

public function setExtensionsData($extensionData)
{
$this->readOnlyException(__METHOD__);
}

public function setExtension($name, $data)
{
$this->readOnlyException(__METHOD__);
}

public function getLocale()
{
return $this->locale;
}

public function setLocale($locale)
{
$this->readOnlyException(__METHOD__);
}

public function getOriginalLocale()
{
return $this->locale;
}

public function setOriginalLocale($locale)
{
$this->readOnlyException(__METHOD__);
}

public function getStructureType()
{
return $this->content->getTemplateKey();
}

public function setStructureType($structureType)
{
$this->readOnlyException(__METHOD__);
}

public function getStructure()
{
return null;
}

protected function readOnlyException($method)
{
throw new \BadMethodCallException(
sprintf(
'Compatibility layer ContentDocument instances are readonly. Tried to call "%s"',
$method
)
);
}
}
Loading

0 comments on commit 9c7b9df

Please sign in to comment.