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

Add AuthorInterface and dynamic settings form #193

Merged
merged 11 commits into from
Jul 30, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ package-lock.json
# tests
Tests/Application/var
Tests/Application/public/build
Tests/Application/.env.local
Tests/Application/.env.test.local
Tests/Application/.env*.local
Tests/reports/

# IDEs
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?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\ContentDataMapper\DataMapper;

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

class AuthorDataMapper implements DataMapperInterface
{
/**
* @var ContactFactoryInterface
*/
private $contactFactory;

public function __construct(ContactFactoryInterface $contactFactory)
{
$this->contactFactory = $contactFactory;
}

public function map(
array $data,
DimensionContentCollectionInterface $dimensionContentCollection
): 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);

return;
}

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

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

if (isset($data['authored'])) {
$dimensionContent->setAuthored(new \DateTimeImmutable($data['authored']));
}
}
}
38 changes: 38 additions & 0 deletions Content/Application/ContentMerger/Merger/AuthorMerger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?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\ContentMerger\Merger;

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

class AuthorMerger implements MergerInterface
{
public function merge(object $targetObject, object $sourceObject): void
{
if (!$targetObject instanceof AuthorInterface) {
return;
}

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

if ($author = $sourceObject->getAuthor()) {
$targetObject->setAuthor($author);
}

if ($authored = $sourceObject->getAuthored()) {
$targetObject->setAuthored($authored);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?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\ContentNormalizer\Normalizer;

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

class AuthorNormalizer implements NormalizerInterface
{
public function enhance(object $object, array $normalizedData): array
{
if (!$object instanceof AuthorInterface) {
return $normalizedData;
}

$normalizedData['author'] = null !== $object->getAuthor() ? $object->getAuthor()->getId() : null;

return $normalizedData;
}

public function getIgnoredAttributes(object $object): array
{
if (!$object instanceof AuthorInterface) {
return [];
}

return ['author'];
}
}
21 changes: 21 additions & 0 deletions Content/Domain/Factory/ContactFactoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?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\Factory;

use Sulu\Bundle\ContactBundle\Entity\ContactInterface;

interface ContactFactoryInterface
{
public function create(?int $contactId): ?ContactInterface;
}
27 changes: 27 additions & 0 deletions Content/Domain/Model/AuthorInterface.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;

use Sulu\Bundle\ContactBundle\Entity\ContactInterface;

interface AuthorInterface
{
public function getAuthor(): ?ContactInterface;

public function setAuthor(?ContactInterface $author): void;

public function getAuthored(): ?\DateTimeImmutable;

public function setAuthored(?\DateTimeImmutable $authored): void;
}
52 changes: 52 additions & 0 deletions Content/Domain/Model/AuthorTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?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;

use Sulu\Bundle\ContactBundle\Entity\ContactInterface;

/**
* Basic implementation of the AuthorTrait.
Prokyonn marked this conversation as resolved.
Show resolved Hide resolved
*/
trait AuthorTrait
{
/**
* @var ContactInterface|null
*/
private $author;

/**
* @var \DateTimeImmutable|null
*/
private $authored;

public function getAuthor(): ?ContactInterface
{
return $this->author;
}

public function setAuthor(?ContactInterface $author): void
{
$this->author = $author;
}

public function getAuthored(): ?\DateTimeImmutable
{
return $this->authored;
}

public function setAuthored(?\DateTimeImmutable $authored): void
{
$this->authored = $authored;
}
}
46 changes: 46 additions & 0 deletions Content/Infrastructure/Doctrine/ContactFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?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\Doctrine;

use Doctrine\ORM\EntityManagerInterface;
use Sulu\Bundle\ContactBundle\Entity\ContactInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Factory\ContactFactoryInterface;

class ContactFactory implements ContactFactoryInterface
{
/**
* @var EntityManagerInterface
*/
private $entityManager;

public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}

public function create(?int $contactId): ?ContactInterface
{
if (!$contactId) {
return null;
}

/** @var ContactInterface|null $contact */
$contact = $this->entityManager->getPartialReference(
ContactInterface::class,
$contactId
);

return $contact;
}
}
12 changes: 10 additions & 2 deletions Content/Infrastructure/Doctrine/MetadataLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
use Doctrine\ORM\Events;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Sulu\Bundle\CategoryBundle\Entity\CategoryInterface;
use Sulu\Bundle\ContactBundle\Entity\ContactInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\AuthorInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\ExcerptInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\SeoInterface;
Expand Down Expand Up @@ -95,6 +97,11 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $event): void
$this->addManyToMany($event, $metadata, 'excerptCategories', CategoryInterface::class, 'category_id');
}

if ($reflection->implementsInterface(AuthorInterface::class)) {
$this->addField($metadata, 'authored', 'datetime_immutable', ['nullable' => true]);
$this->addManyToOne($event, $metadata, 'author', ContactInterface::class, true);
}

if ($reflection->implementsInterface(WorkflowInterface::class)) {
$this->addField($metadata, 'workflowPlace', 'string', ['length' => 32, 'nullable' => true]);
$this->addField($metadata, 'workflowPublished', 'datetime_immutable', ['nullable' => true]);
Expand All @@ -110,7 +117,8 @@ private function addManyToOne(
LoadClassMetadataEventArgs $event,
ClassMetadataInfo $metadata,
string $name,
string $class
string $class,
bool $nullable = false
): void {
if ($metadata->hasAssociation($name)) {
return;
Expand All @@ -126,7 +134,7 @@ private function addManyToOne(
[
'name' => $namingStrategy->joinKeyColumnName($name),
'referencedColumnName' => $referencedColumnName,
'nullable' => false,
'nullable' => $nullable,
'onDelete' => 'CASCADE',
'onUpdate' => 'CASCADE',
],
Expand Down
Loading