Skip to content

Commit

Permalink
Add Shadow Locale to Settings Tab
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-schranz committed Mar 21, 2023
1 parent 78249df commit 44e8188
Show file tree
Hide file tree
Showing 24 changed files with 392 additions and 2 deletions.
@@ -0,0 +1,49 @@
<?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\DimensionContentInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\ShadowInterface;

class ShadowDataMapper implements DataMapperInterface
{
public function map(
DimensionContentInterface $unlocalizedDimensionContent,
DimensionContentInterface $localizedDimensionContent,
array $data
): void {
if (!$localizedDimensionContent instanceof ShadowInterface) {
return;
}

if (!$unlocalizedDimensionContent instanceof ShadowInterface) {
return;
}

if (\array_key_exists('shadowOn', $data) || \array_key_exists('shadowLocale', $data)) {
/** @var bool $shadowOn */
$shadowOn = $data['shadowOn'] ?? false;
/** @var string|null $shadowLocale */
$shadowLocale = $data['shadowLocale'] ?? null;

$localizedDimensionContent->setShadowLocale(
$shadowOn
? $shadowLocale
: null
);
}
}
}
42 changes: 42 additions & 0 deletions Content/Application/ContentMerger/Merger/ShadowMerger.php
@@ -0,0 +1,42 @@
<?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\ShadowInterface;

/**
* @internal This class should not be instantiated by a project.
* Create your own merger instead.
*/
final class ShadowMerger implements MergerInterface
{
public function merge(object $targetObject, object $sourceObject): void
{
if (!$targetObject instanceof ShadowInterface) {
return;
}

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

if ($shadowLocale = $sourceObject->getShadowLocale()) {
$targetObject->setShadowLocale($shadowLocale);
}

foreach ($sourceObject->getShadowLocales() ?: [] as $locale => $shadowLocale) {
$targetObject->addShadowLocale($locale, $shadowLocale);
}
}
}
@@ -0,0 +1,45 @@
<?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\DimensionContentInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\ShadowInterface;
use Webmozart\Assert\Assert;

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

Assert::isInstanceOf($object, DimensionContentInterface::class);

$normalizedData['shadowOn'] = $object->getShadowLocale() !== null;
$normalizedData['shadowLocales'] = $object->getShadowLocales() ?? [];
$normalizedData['contentLocales'] = $object->getAvailableLocales() ?? []; // TODO should be changed in Sulu Core (PageSettingsShadowLocaleSelect.js)

return $normalizedData;
}

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

return [];
}
}
39 changes: 39 additions & 0 deletions Content/Domain/Model/ShadowInterface.php
@@ -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\Domain\Model;

interface ShadowInterface
{
/**
* @internal should only be set by content bundle services not from outside
*/
public function setShadowLocale(?string $shadowLocale): void;

public function getShadowLocale(): ?string;

/**
* @internal should only be set by content bundle services not from outside
*/
public function addShadowLocale(string $locale, string $shadowLocale): void;

/**
* @internal should only be set by content bundle services not from outside
*/
public function removeShadowLocale(string $locale): void;

/**
* @return array<string, string>|null
*/
public function getShadowLocales(): ?array;
}
68 changes: 68 additions & 0 deletions Content/Domain/Model/ShadowTrait.php
@@ -0,0 +1,68 @@
<?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;

trait ShadowTrait
{
/**
* @var string|null
*/
protected $shadowLocale;

/**
* @var string[]|null
*/
protected $shadowLocales = null;

/**
* @internal should only be set by content bundle services not from outside
*/
public function setShadowLocale(?string $shadowLocale): void
{
$this->shadowLocale = $shadowLocale;
}

public function getShadowLocale(): ?string
{
return $this->shadowLocale;
}

/**
* @internal should only be set by content bundle services not from outside
*/
public function addShadowLocale(string $locale, string $shadowLocale): void
{
if (null === $this->shadowLocales) {
$this->shadowLocales = [];
}

$this->shadowLocales[$locale] = $shadowLocale;
}

/**
* @internal should only be set by content bundle services not from outside
*/
public function removeShadowLocale(string $locale): void
{
unset($this->shadowLocales[$locale]);
}

/**
* @return array<string, string>
*/
public function getShadowLocales(): ?array
{
return $this->shadowLocales;
}
}
8 changes: 7 additions & 1 deletion Content/Infrastructure/Doctrine/MetadataLoader.php
Expand Up @@ -25,6 +25,7 @@
use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\ExcerptInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\SeoInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\ShadowInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\TemplateInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\WebspaceInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\WorkflowInterface;
Expand Down Expand Up @@ -53,7 +54,7 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $event): void
$this->addField($metadata, 'stage', 'string', ['length' => 16, 'nullable' => false]);
$this->addField($metadata, 'locale', 'string', ['length' => 7, 'nullable' => true]);
$this->addField($metadata, 'ghostLocale', 'string', ['length' => 7, 'nullable' => true]);
$this->addField($metadata, 'availableLocales', 'json', ['nullable' => true]);
$this->addField($metadata, 'availableLocales', 'json', ['nullable' => true, 'options' => ['jsonb' => true]]);
$this->addIndex($metadata, 'idx_dimension', ['stage', 'locale']);
$this->addIndex($metadata, 'idx_locale', ['locale']);
$this->addIndex($metadata, 'idx_stage', ['stage']);
Expand Down Expand Up @@ -110,6 +111,11 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $event): void
$this->addField($metadata, 'mainWebspace', 'string', ['nullable' => true]);
}

if ($reflection->implementsInterface(ShadowInterface::class)) {
$this->addField($metadata, 'shadowLocale', 'string', ['length' => 7, 'nullable' => true]);
$this->addField($metadata, 'shadowLocales', 'json', ['nullable' => true, 'options' => ['jsonb' => true]]);
}

if ($reflection->implementsInterface(AuthorInterface::class)) {
$this->addField($metadata, 'authored', 'datetime_immutable', ['nullable' => true]);
$this->addManyToOne($event, $metadata, 'author', ContactInterface::class, true);
Expand Down
12 changes: 12 additions & 0 deletions Content/Infrastructure/Sulu/Admin/ContentViewBuilderFactory.php
Expand Up @@ -22,12 +22,16 @@
use Sulu\Bundle\ContentBundle\Content\Application\ContentMetadataInspector\ContentMetadataInspectorInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\ExcerptInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\SeoInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\ShadowInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\TemplateInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\WorkflowInterface;
use Sulu\Bundle\PreviewBundle\Preview\Object\PreviewObjectProviderRegistryInterface;
use Sulu\Component\Security\Authorization\PermissionTypes;
use Sulu\Component\Security\Authorization\SecurityCheckerInterface;

/**
* @final
*/
class ContentViewBuilderFactory implements ContentViewBuilderFactoryInterface
{
/**
Expand Down Expand Up @@ -217,6 +221,14 @@ public function createViews(
);
}

if (\is_subclass_of($dimensionContentClass, ShadowInterface::class)) {
foreach ($views as $view) {
if ($view instanceof FormViewBuilderInterface || $view instanceof PreviewFormViewBuilderInterface) {
$view->setTabCondition('shadowOn != true');
}
}
}

$views[] = $this->createSettingsFormView(
$editParentView,
$previewEnabled,
Expand Down
4 changes: 4 additions & 0 deletions Resources/config/data-mapper.xml
Expand Up @@ -38,6 +38,10 @@
<tag name="sulu_content.data_mapper" priority="8"/>
</service>

<service id="sulu_content.shadow_data_mapper" class="Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper\ShadowDataMapper">
<tag name="sulu_content.data_mapper" priority="4"/>
</service>

<service id="sulu_content.route_data_mapper" class="Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper\RoutableDataMapper">
<argument type="service" id="sulu_page.structure.factory"/>
<argument type="service" id="sulu_route.generator.route_generator"/>
Expand Down
40 changes: 40 additions & 0 deletions Resources/config/forms/content_settings_shadow.xml
@@ -0,0 +1,40 @@
<?xml version="1.0" ?>
<form xmlns="http://schemas.sulu.io/template/template"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://schemas.sulu.io/template/template http://schemas.sulu.io/template/form-1.0.xsd"
>
<key>content_settings_shadow</key>

<tag name="sulu_content.content_settings_form" instanceOf="Sulu\Bundle\ContentBundle\Content\Domain\Model\ShadowInterface" priority="-40"/>

<properties>
<section name="shadow">
<meta>
<title>sulu_content.shadow_page</title>
</meta>

<properties>
<property name="shadowOn" type="checkbox" disabledCondition="shadowLocales and __locale in shadowLocales|values">
<meta>
<info_text>sulu_content.enable_shadow_page_info_text</info_text>
</meta>

<params>
<param name="type" value="toggler" />
<param name="label">
<meta>
<title>sulu_content.enable_shadow_page</title>
</meta>
</param>
</params>
</property>

<property name="shadowLocale" type="page_settings_shadow_locale_select" colspan="6" visibleCondition="shadowOn == true">
<meta>
<title>sulu_content.shadow_locale</title>
</meta>
</property>
</properties>
</section>
</properties>
</form>
4 changes: 4 additions & 0 deletions Resources/config/merger.xml
Expand Up @@ -31,5 +31,9 @@
<service id="sulu_content.author_merger" class="Sulu\Bundle\ContentBundle\Content\Application\ContentMerger\Merger\AuthorMerger">
<tag name="sulu_content.merger" priority="8"/>
</service>

<service id="sulu_content.shadow_merger" class="Sulu\Bundle\ContentBundle\Content\Application\ContentMerger\Merger\ShadowMerger">
<tag name="sulu_content.merger" priority="4"/>
</service>
</services>
</container>
4 changes: 4 additions & 0 deletions Resources/config/normalizer.xml
Expand Up @@ -27,5 +27,9 @@
<service id="sulu_content.author_normalizer" class="Sulu\Bundle\ContentBundle\Content\Application\ContentNormalizer\Normalizer\AuthorNormalizer">
<tag name="sulu_content.normalizer" priority="8"/>
</service>

<service id="sulu_content.shadow_normalizer" class="Sulu\Bundle\ContentBundle\Content\Application\ContentNormalizer\Normalizer\ShadowNormalizer">
<tag name="sulu_content.normalizer" priority="4"/>
</service>
</services>
</container>
4 changes: 4 additions & 0 deletions Resources/translations/admin.de.json
Expand Up @@ -5,6 +5,10 @@
"sulu_content.published": "Veröffentlicht am",
"sulu_content.author": "Autor",
"sulu_content.authored_date": "Verfasst am",
"sulu_content.shadow_page": "Shadow Seite",
"sulu_content.enable_shadow_page": "Shadow Seite aktivieren",
"sulu_content.enable_shadow_page_info_text": "",
"sulu_content.shadow_locale": "Shadow sprache",
"sulu_content.webspace": "Webspace",
"sulu_content.main_webspace": "Hauptwebspace",
"sulu_content.additional_webspaces": "Weitere Webspaces"
Expand Down

0 comments on commit 44e8188

Please sign in to comment.