Skip to content

Commit

Permalink
Merge pull request #533 from BitBagCommerce/feature/OP-525
Browse files Browse the repository at this point in the history
OP-525: Content migration script
jkindly authored Sep 24, 2024
2 parents 3740621 + c8dc43a commit 4b028d9
Showing 30 changed files with 493 additions and 139 deletions.
2 changes: 2 additions & 0 deletions doc/block_legacy.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
code,type,name_en_US,content_en_US,sections,channels,products,image_en_US,slug_en_US
test4,image,Test,test,"blog, general",US_WEB,"010ba66b-adee-3d6e-9d63-67c44d686db1, 01d35db9-247d-3834-b300-20483d5e34e8",https://bitbag.shop/assets/web/images/header-logo.png,https://bitbag.shop/assets/web/images/header-logo.png
49 changes: 49 additions & 0 deletions doc/legacy_data_migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Legacy data migration

## Introduction

You can migrate your blocks & pages from the 4.x version to the 5.x version of the plugin.
To do so, you need to follow the steps below.

## Steps

1. Create new CSV files with blocks & pages data in the 4.x format.
See an example in [block_legacy.csv](block_legacy.csv) or [page_legacy.csv](page_legacy.csv).
2. Install the 5.x version of the plugin.
3. Go to the console and run the following command:
```bash
bin/console cms:import:csv page_legacy {file_path}.csv
bin/console cms:import:csv block_legacy {file_path}.csv
```

## Info about legacy CSV files columns

### Blocks

- **code** - block code.
- **type** - it will be ignored.
- **name_LOCALE** - block name. First occurrence of its column is the default name for the block.
For each locale, there will be created a Heading content element.
- **content_LOCALE** - block content. For each locale, there will be created a Textarea content element.
- **sections** - it will be converted to the block's collections.
- **channels** - block channels.
- **products** - block products. There will be created Products grid content element.
- **image_LOCALE** - block image. For each locale, there will be created a Single media content element.
- **slug_LOCALE** - it will be ignored.

### Pages

- **code** - page code.
- **sections** - it will be converted to the page's collections.
- **channels** - page channels.
- **products** - page products. There will be created Products grid content element.
- **slug_LOCALE** - page slug.
- **name_LOCALE** - page name. First occurrence of its column is the default name for the page.
For each locale, there will be created a Heading content element.
- **image_LOCALE** - page image. For each locale, there will be created a Single media content element.
- **meta_keywords_LOCALE** - page meta keywords.
- **meta_description_LOCALE** - page meta description.
- **content_LOCALE** - page content. For each locale, there will be created a Textarea content element.
- **breadcrumb_LOCALE** - it will be ignored.
- **name_when_linked_LOCALE** - for each locale, there will be created a teaser title.
- **description_when_linked_LOCALE** - for each locale, there will be created a teaser content.
2 changes: 2 additions & 0 deletions doc/page_legacy.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
code,sections,channels,products,slug_en_US,name_en_US,image_en_US,meta_keywords_en_US,meta_description_en_US,content_en_US,breadcrumb_en_US,name_when_linked_en_US,description_when_linked_en_US
aboutUS,,US_WEB,,about_us,About US,,About US,About US,"",,,
4 changes: 0 additions & 4 deletions spec/Importer/BlockImporterSpec.php
Original file line number Diff line number Diff line change
@@ -25,7 +25,6 @@ public function let(
ResourceResolverInterface $blockResourceResolver,
ImporterCollectionsResolverInterface $importerCollectionsResolver,
ImporterChannelsResolverInterface $importerChannelsResolver,
ImporterLocalesResolverInterface $importerLocalesResolver,
ImporterProductsResolverInterface $importerProductsResolver,
ImporterTaxonsResolverInterface $importerTaxonsResolver,
ImporterProductsInTaxonsResolverInterface $importerProductsInTaxonsResolver,
@@ -36,7 +35,6 @@ public function let(
$blockResourceResolver,
$importerCollectionsResolver,
$importerChannelsResolver,
$importerLocalesResolver,
$importerProductsResolver,
$importerTaxonsResolver,
$importerProductsInTaxonsResolver,
@@ -55,7 +53,6 @@ public function it_imports_block(
ResourceResolverInterface $blockResourceResolver,
ImporterCollectionsResolverInterface $importerCollectionsResolver,
ImporterChannelsResolverInterface $importerChannelsResolver,
ImporterLocalesResolverInterface $importerLocalesResolver,
ImporterProductsResolverInterface $importerProductsResolver,
ImporterTaxonsResolverInterface $importerTaxonsResolver,
ImporterProductsInTaxonsResolverInterface $importerProductsInTaxonsResolver,
@@ -73,7 +70,6 @@ public function it_imports_block(

$importerCollectionsResolver->resolve($block, null)->shouldBeCalled();
$importerChannelsResolver->resolve($block, null)->shouldBeCalled();
$importerLocalesResolver->resolve($block, null)->shouldBeCalled();
$importerProductsResolver->resolve($block, null)->shouldBeCalled();
$importerTaxonsResolver->resolve($block, null)->shouldBeCalled();
$importerProductsInTaxonsResolver->resolve($block, null)->shouldBeCalled();
61 changes: 0 additions & 61 deletions spec/Resolver/BlockResourceResolverSpec.php
Original file line number Diff line number Diff line change
@@ -4,7 +4,6 @@

namespace spec\Sylius\CmsPlugin\Resolver;

use Doctrine\Common\Collections\ArrayCollection;
use PhpSpec\ObjectBehavior;
use Psr\Log\LoggerInterface;
use Sylius\CmsPlugin\Entity\BlockInterface;
@@ -14,7 +13,6 @@
use Sylius\Component\Channel\Context\ChannelContextInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Locale\Context\LocaleContextInterface;
use Sylius\Component\Locale\Model\LocaleInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;

final class BlockResourceResolverSpec extends ObjectBehavior
@@ -39,74 +37,15 @@ public function it_implements_block_resource_resolver_interface(): void
$this->shouldHaveType(BlockResourceResolverInterface::class);
}

public function it_logs_warning_if_block_was_not_found(
BlockRepositoryInterface $blockRepository,
LoggerInterface $logger,
ChannelContextInterface $channelContext,
ChannelInterface $channel,
) {
$channel->getCode()->willReturn('WEB');
$channelContext->getChannel()->willReturn($channel);
$blockRepository->findEnabledByCode('homepage_banner', 'WEB')->willReturn(null);

$logger
->warning(sprintf(
'Block with "%s" code was not found in the database.',
'homepage_banner',
))
->shouldBeCalled()
;

$this->findOrLog('homepage_banner');
}

public function it_logs_warning_if_block_was_found_but_it_does_not_have_locale(
BlockRepositoryInterface $blockRepository,
LoggerInterface $logger,
ChannelContextInterface $channelContext,
ChannelInterface $channel,
LocaleContextInterface $localeContext,
LocaleInterface $locale,
RepositoryInterface $localeRepository,
BlockInterface $block,
) {
$channel->getCode()->willReturn('WEB');
$channelContext->getChannel()->willReturn($channel);
$blockRepository->findEnabledByCode('homepage_banner', 'WEB')->willReturn($block);
$localeContext->getLocaleCode()->willReturn('en_US');
$locale->getCode()->willReturn('en_US');
$localeRepository->findOneBy(['code' => 'en_US'])->willReturn($locale);
$block->hasLocale($locale)->willReturn(false);
$block->getLocales()->willReturn(new ArrayCollection(['pl_PL']));

$logger
->warning(sprintf(
'Block with "%s" code was found in the database, but it does not have "%s" locale.',
'homepage_banner',
'en_US',
))
->shouldBeCalled()
;

$this->findOrLog('homepage_banner');
}

public function it_returns_block_if_found_in_database(
BlockRepositoryInterface $blockRepository,
BlockInterface $block,
ChannelContextInterface $channelContext,
ChannelInterface $channel,
LocaleContextInterface $localeContext,
LocaleInterface $locale,
RepositoryInterface $localeRepository,
) {
$channel->getCode()->willReturn('WEB');
$channelContext->getChannel()->willReturn($channel);
$blockRepository->findEnabledByCode('homepage_banner', 'WEB')->willReturn($block);
$localeContext->getLocaleCode()->willReturn('en_US');
$locale->getCode()->willReturn('en_US');
$localeRepository->findOneBy(['code' => 'en_US'])->willReturn($locale);
$block->hasLocale($locale)->willReturn(true);

$this->findOrLog('homepage_banner')->shouldReturn($block);
}
3 changes: 0 additions & 3 deletions src/Entity/Block.php
Original file line number Diff line number Diff line change
@@ -7,7 +7,6 @@
use Sylius\CmsPlugin\Entity\Trait\ChannelsAwareTrait;
use Sylius\CmsPlugin\Entity\Trait\CollectibleTrait;
use Sylius\CmsPlugin\Entity\Trait\ContentElementsAwareTrait;
use Sylius\CmsPlugin\Entity\Trait\LocaleAwareTrait;
use Sylius\CmsPlugin\Entity\Trait\ProductsAwareTrait;
use Sylius\CmsPlugin\Entity\Trait\ProductsInTaxonsAwareTrait;
use Sylius\CmsPlugin\Entity\Trait\TaxonAwareTrait;
@@ -19,7 +18,6 @@ class Block implements BlockInterface
use CollectibleTrait;
use ChannelsAwareTrait;
use ContentElementsAwareTrait;
use LocaleAwareTrait;
use ProductsAwareTrait;
use TaxonAwareTrait;
use ProductsInTaxonsAwareTrait;
@@ -29,7 +27,6 @@ public function __construct()
$this->initializeCollectionsCollection();
$this->initializeChannelsCollection();
$this->initializeContentElementsCollection();
$this->initializeLocalesCollection();
$this->initializeProductsCollection();
$this->initializeTaxonCollection();
$this->initializeProductsInTaxonsCollection();
1 change: 0 additions & 1 deletion src/Entity/BlockInterface.php
Original file line number Diff line number Diff line change
@@ -14,7 +14,6 @@ interface BlockInterface extends
CollectibleInterface,
ChannelsAwareInterface,
ContentElementsAwareInterface,
LocaleAwareInterface,
ProductsAwareInterface,
TaxonAwareInterface,
ProductsInTaxonsAwareInterface,
85 changes: 85 additions & 0 deletions src/Factory/ContentElementFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

declare(strict_types=1);

namespace Sylius\CmsPlugin\Factory;

use Sylius\CmsPlugin\Entity\ContentConfiguration;

final class ContentElementFactory
{
public static function createHeadingContentElement(
?string $locale,
?string $headingType,
?string $headingContent,
): ?ContentConfiguration {
if (null === $headingContent) {
return null;
}

$contentConfiguration = new ContentConfiguration();
$contentConfiguration->setLocale($locale ?? 'en_US');
$contentConfiguration->setType('heading');
$contentConfiguration->setConfiguration([
'heading_type' => $headingType ?? 'h1',
'heading' => $headingContent,
]);

return $contentConfiguration;
}

public static function createTextareaContentElement(?string $locale, ?string $content): ?ContentConfiguration
{
if (null === $content) {
return null;
}

$contentConfiguration = new ContentConfiguration();
$contentConfiguration->setLocale($locale ?? 'en_US');
$contentConfiguration->setType('textarea');
$contentConfiguration->setConfiguration([
'textarea' => $content,
]);

return $contentConfiguration;
}

public static function createProductsGridContentElement(?string $locale, ?string $codes): ?ContentConfiguration
{
if (null === $codes) {
return null;
}

$productsCodes = explode(',', $codes);
$productsCodes = array_map(static function (string $element): string {
return trim($element);
}, $productsCodes);

$contentConfiguration = new ContentConfiguration();
$contentConfiguration->setLocale($locale ?? 'en_US');
$contentConfiguration->setType('products_grid');
$contentConfiguration->setConfiguration([
'products_grid' => [
'products' => $productsCodes,
],
]);

return $contentConfiguration;
}

public static function createSingleMediaContentElement(?string $locale, ?string $code): ?ContentConfiguration
{
if (null === $code) {
return null;
}

$contentConfiguration = new ContentConfiguration();
$contentConfiguration->setLocale($locale ?? 'en_US');
$contentConfiguration->setType('single_media');
$contentConfiguration->setConfiguration([
'single_media' => $code,
]);

return $contentConfiguration;
}
}
1 change: 0 additions & 1 deletion src/Fixture/BlockFixture.php
Original file line number Diff line number Diff line change
@@ -36,7 +36,6 @@ protected function configureOptionsNode(ArrayNodeDefinition $optionsNode): void
->booleanNode('enabled')->defaultTrue()->end()
->arrayNode('collections')->scalarPrototype()->end()->end()
->arrayNode('channels')->scalarPrototype()->end()->end()
->arrayNode('locales')->scalarPrototype()->end()->end()
->arrayNode('products')->scalarPrototype()->end()->end()
->arrayNode('taxons')->scalarPrototype()->end()->end()
->arrayNode('products_in_taxons')->scalarPrototype()->end()->end()
3 changes: 0 additions & 3 deletions src/Fixture/Factory/BlockFixtureFactory.php
Original file line number Diff line number Diff line change
@@ -6,7 +6,6 @@

use Sylius\CmsPlugin\Assigner\ChannelsAssignerInterface;
use Sylius\CmsPlugin\Assigner\CollectionsAssignerInterface;
use Sylius\CmsPlugin\Assigner\LocalesAssignerInterface;
use Sylius\CmsPlugin\Assigner\ProductsAssignerInterface;
use Sylius\CmsPlugin\Assigner\ProductsInTaxonsAssignerInterface;
use Sylius\CmsPlugin\Assigner\TaxonsAssignerInterface;
@@ -22,7 +21,6 @@ public function __construct(
private BlockRepositoryInterface $blockRepository,
private CollectionsAssignerInterface $collectionsAssigner,
private ChannelsAssignerInterface $channelAssigner,
private LocalesAssignerInterface $localesAssigner,
private ProductsAssignerInterface $productsAssigner,
private TaxonsAssignerInterface $taxonsAssigner,
private ProductsInTaxonsAssignerInterface $productsInTaxonsAssigner,
@@ -56,7 +54,6 @@ private function createBlock(string $code, array $blockData): void

$this->collectionsAssigner->assign($block, $blockData['collections']);
$this->channelAssigner->assign($block, $blockData['channels']);
$this->localesAssigner->assign($block, $blockData['locales']);
$this->productsAssigner->assign($block, $blockData['products']);
$this->taxonsAssigner->assign($block, $blockData['taxons']);
$this->productsInTaxonsAssigner->assign($block, $blockData['products_in_taxons']);
1 change: 0 additions & 1 deletion src/Form/Type/BlockType.php
Original file line number Diff line number Diff line change
@@ -61,7 +61,6 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'multiple' => true,
'expanded' => true,
])
->add('locales')
->add('contentElements', CollectionType::class, [
'label' => false,
'entry_type' => ContentConfigurationType::class,
8 changes: 5 additions & 3 deletions src/Importer/AbstractImporter.php
Original file line number Diff line number Diff line change
@@ -35,13 +35,15 @@ protected function getTranslatableColumnValue(
protected function getAvailableLocales(array $translatableColumns, array $columns): array
{
$locales = [];

foreach ($translatableColumns as $translatableColumn) {
$translatableColumn = str_replace('__locale__', '_', $translatableColumn);

foreach ($columns as $column) {
if (str_starts_with($column, $translatableColumn)) {
$locales[] = str_replace($translatableColumn, '', $column);
$localePart = substr($column, strlen($translatableColumn));

if (preg_match('/^[a-z]{2}(_[A-Z]{2})?$/', $localePart)) {
$locales[] = $localePart;
}
}
}
}
3 changes: 0 additions & 3 deletions src/Importer/BlockImporter.php
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@
use Sylius\CmsPlugin\Repository\BlockRepositoryInterface;
use Sylius\CmsPlugin\Resolver\Importer\ImporterChannelsResolverInterface;
use Sylius\CmsPlugin\Resolver\Importer\ImporterCollectionsResolverInterface;
use Sylius\CmsPlugin\Resolver\Importer\ImporterLocalesResolverInterface;
use Sylius\CmsPlugin\Resolver\Importer\ImporterProductsInTaxonsResolverInterface;
use Sylius\CmsPlugin\Resolver\Importer\ImporterProductsResolverInterface;
use Sylius\CmsPlugin\Resolver\Importer\ImporterTaxonsResolverInterface;
@@ -22,7 +21,6 @@ public function __construct(
private ResourceResolverInterface $blockResourceResolver,
private ImporterCollectionsResolverInterface $importerCollectionsResolver,
private ImporterChannelsResolverInterface $importerChannelsResolver,
private ImporterLocalesResolverInterface $importerLocalesResolver,
private ImporterProductsResolverInterface $importerProductsResolver,
private ImporterTaxonsResolverInterface $importerTaxonsResolver,
private ImporterProductsInTaxonsResolverInterface $importerProductsInTaxonsResolver,
@@ -45,7 +43,6 @@ public function import(array $row): void

$this->importerCollectionsResolver->resolve($block, $this->getColumnValue(self::COLLECTIONS_COLUMN, $row));
$this->importerChannelsResolver->resolve($block, $this->getColumnValue(self::CHANNELS_COLUMN, $row));
$this->importerLocalesResolver->resolve($block, $this->getColumnValue(self::LOCALES_COLUMN, $row));
$this->importerProductsResolver->resolve($block, $this->getColumnValue(self::PRODUCTS_COLUMN, $row));
$this->importerTaxonsResolver->resolve($block, $this->getColumnValue(self::TAXONS_COLUMN, $row));
$this->importerProductsInTaxonsResolver->resolve($block, $this->getColumnValue(self::PRODUCTS_IN_TAXONS_COLUMN, $row));
2 changes: 0 additions & 2 deletions src/Importer/BlockImporterInterface.php
Original file line number Diff line number Diff line change
@@ -14,8 +14,6 @@ interface BlockImporterInterface extends ImporterInterface

public const COLLECTIONS_COLUMN = 'collections';

public const LOCALES_COLUMN = 'locales';

public const CHANNELS_COLUMN = 'channels';

public const PRODUCTS_COLUMN = 'products';
109 changes: 109 additions & 0 deletions src/Importer/Legacy/LegacyBlockImporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php

declare(strict_types=1);

namespace Sylius\CmsPlugin\Importer\Legacy;

use Sylius\CmsPlugin\Entity\BlockInterface;
use Sylius\CmsPlugin\Factory\ContentElementFactory;
use Sylius\CmsPlugin\Importer\AbstractImporter;
use Sylius\CmsPlugin\Repository\BlockRepositoryInterface;
use Sylius\CmsPlugin\Resolver\Importer\ImporterChannelsResolverInterface;
use Sylius\CmsPlugin\Resolver\Importer\ImporterCollectionsResolverInterface;
use Sylius\CmsPlugin\Resolver\ResourceResolverInterface;
use Sylius\Component\Locale\Model\LocaleInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Webmozart\Assert\Assert;

final class LegacyBlockImporter extends AbstractImporter implements LegacyBlockImporterInterface
{
public function __construct(
private ResourceResolverInterface $blockResourceResolver,
private ImporterCollectionsResolverInterface $importerCollectionsResolver,
private ImporterChannelsResolverInterface $importerChannelsResolver,
private BlockRepositoryInterface $blockRepository,
private RepositoryInterface $localeRepository,
ValidatorInterface $validator,
) {
parent::__construct($validator);
}

public function import(array $row): void
{
/** @var string|null $code */
$code = $this->getColumnValue(self::CODE_COLUMN, $row);
Assert::notNull($code);
/** @var BlockInterface $block */
$block = $this->blockResourceResolver->getResource($code);
$block->setCode($code);

$this->importerCollectionsResolver->resolve($block, $this->getColumnValue(self::SECTIONS_COLUMN, $row));
$this->importerChannelsResolver->resolve($block, $this->getColumnValue(self::CHANNELS_COLUMN, $row));

$translationArray = $this->getAvailableLocales($this->getTranslatableColumns(), array_keys($row));
foreach ($translationArray as $key => $locale) {
if ($key === array_key_first($translationArray)) {
$block->setName($this->getTranslatableColumnValue(self::NAME_COLUMN, $locale, $row));
}

$heading = ContentElementFactory::createHeadingContentElement(
$locale,
'h2',
$this->getTranslatableColumnValue(self::NAME_COLUMN, $locale, $row),
);
if ($heading) {
$heading->setBlock($block);
$block->addContentElement($heading);
}

$singleMedia = ContentElementFactory::createSingleMediaContentElement(
$locale,
$this->getTranslatableColumnValue(self::IMAGE_COLUMN, $locale, $row),
);
if ($singleMedia) {
$singleMedia->setBlock($block);
$block->addContentElement($singleMedia);
}

$content = ContentElementFactory::createTextareaContentElement(
$locale,
$this->getTranslatableColumnValue(self::CONTENT_COLUMN, $locale, $row),
);
if ($content) {
$content->setBlock($block);
$block->addContentElement($content);
}
}

$locales = $this->localeRepository->findAll();
/** @var LocaleInterface $locale */
foreach ($locales as $locale) {
$productsGrid = ContentElementFactory::createProductsGridContentElement(
$locale->getCode(),
$this->getColumnValue(self::PRODUCTS_COLUMN, $row),
);
if ($productsGrid) {
$productsGrid->setBlock($block);
$block->addContentElement($productsGrid);
}
}

$this->validateResource($block, ['cms']);
$this->blockRepository->add($block);
}

public function getResourceCode(): string
{
return 'block_legacy';
}

private function getTranslatableColumns(): array
{
return [
self::NAME_COLUMN,
self::CONTENT_COLUMN,
self::IMAGE_COLUMN,
];
}
}
24 changes: 24 additions & 0 deletions src/Importer/Legacy/LegacyBlockImporterInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Sylius\CmsPlugin\Importer\Legacy;

use Sylius\CmsPlugin\Importer\ImporterInterface;

interface LegacyBlockImporterInterface extends ImporterInterface
{
public const CODE_COLUMN = 'code';

public const SECTIONS_COLUMN = 'sections';

public const CHANNELS_COLUMN = 'channels';

public const PRODUCTS_COLUMN = 'products';

public const NAME_COLUMN = 'name__locale__';

public const CONTENT_COLUMN = 'content__locale__';

public const IMAGE_COLUMN = 'image__locale__';
}
129 changes: 129 additions & 0 deletions src/Importer/Legacy/LegacyPageImporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php

declare(strict_types=1);

namespace Sylius\CmsPlugin\Importer\Legacy;

use Doctrine\ORM\EntityManagerInterface;
use Sylius\CmsPlugin\Entity\PageInterface;
use Sylius\CmsPlugin\Factory\ContentElementFactory;
use Sylius\CmsPlugin\Importer\AbstractImporter;
use Sylius\CmsPlugin\Resolver\Importer\ImporterChannelsResolverInterface;
use Sylius\CmsPlugin\Resolver\Importer\ImporterCollectionsResolverInterface;
use Sylius\CmsPlugin\Resolver\ResourceResolverInterface;
use Sylius\Component\Locale\Context\LocaleContextInterface;
use Sylius\Component\Locale\Model\LocaleInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Webmozart\Assert\Assert;

final class LegacyPageImporter extends AbstractImporter implements LegacyPageImporterInterface
{
public function __construct(
private ResourceResolverInterface $pageResourceResolver,
private LocaleContextInterface $localeContext,
private ImporterCollectionsResolverInterface $importerCollectionsResolver,
private ImporterChannelsResolverInterface $importerChannelsResolver,
private EntityManagerInterface $entityManager,
private RepositoryInterface $localeRepository,
ValidatorInterface $validator,
) {
parent::__construct($validator);
}

public function import(array $row): void
{
/** @var string|null $code */
$code = $this->getColumnValue(self::CODE_COLUMN, $row);
Assert::notNull($code);

/** @var PageInterface $page */
$page = $this->pageResourceResolver->getResource($code);

$page->setCode($code);
$page->setFallbackLocale($this->localeContext->getLocaleCode());

$this->importerCollectionsResolver->resolve($page, $this->getColumnValue(self::SECTIONS_COLUMN, $row));
$this->importerChannelsResolver->resolve($page, $this->getColumnValue(self::CHANNELS_COLUMN, $row));

$translationArray = $this->getAvailableLocales($this->getTranslatableColumns(), array_keys($row));
foreach ($translationArray as $key => $locale) {
$page->setCurrentLocale($locale);
$page->setSlug($this->getTranslatableColumnValue(self::SLUG_COLUMN, $locale, $row));
$page->setMetaKeywords($this->getTranslatableColumnValue(self::META_KEYWORDS_COLUMN, $locale, $row));
$page->setMetaDescription($this->getTranslatableColumnValue(self::META_DESCRIPTION_COLUMN, $locale, $row));

if ($key === array_key_first($translationArray)) {
$page->setName($this->getTranslatableColumnValue(self::NAME_COLUMN, $locale, $row));
}

$page->setTeaserTitle($this->getTranslatableColumnValue(self::NAME_WHEN_LINKED_COLUMN, $locale, $row));
$page->setTeaserContent($this->getTranslatableColumnValue(self::DESCRIPTION_WHEN_LINKED_COLUMN, $locale, $row));

$heading = ContentElementFactory::createHeadingContentElement(
$locale,
'h2',
$this->getTranslatableColumnValue(self::NAME_COLUMN, $locale, $row),
);
if ($heading) {
$heading->setPage($page);
$page->addContentElement($heading);
}

$singleMedia = ContentElementFactory::createSingleMediaContentElement(
$locale,
$this->getTranslatableColumnValue(self::IMAGE_COLUMN, $locale, $row),
);
if ($singleMedia) {
$singleMedia->setPage($page);
$page->addContentElement($singleMedia);
}

$content = ContentElementFactory::createTextareaContentElement(
$locale,
$this->getTranslatableColumnValue(self::CONTENT_COLUMN, $locale, $row),
);
if ($content) {
$content->setPage($page);
$page->addContentElement($content);
}
}

$locales = $this->localeRepository->findAll();
/** @var LocaleInterface $locale */
foreach ($locales as $locale) {
$productsGrid = ContentElementFactory::createProductsGridContentElement(
$locale->getCode(),
$this->getColumnValue(self::PRODUCTS_COLUMN, $row),
);
if ($productsGrid) {
$productsGrid->setPage($page);
$page->addContentElement($productsGrid);
}
}

$this->validateResource($page, ['cms']);

$this->entityManager->persist($page);
$this->entityManager->flush();
}

public function getResourceCode(): string
{
return 'page_legacy';
}

private function getTranslatableColumns(): array
{
return [
self::SLUG_COLUMN,
self::NAME_COLUMN,
self::IMAGE_COLUMN,
self::CONTENT_COLUMN,
self::META_KEYWORDS_COLUMN,
self::META_DESCRIPTION_COLUMN,
self::NAME_WHEN_LINKED_COLUMN,
self::DESCRIPTION_WHEN_LINKED_COLUMN,
];
}
}
34 changes: 34 additions & 0 deletions src/Importer/Legacy/LegacyPageImporterInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Sylius\CmsPlugin\Importer\Legacy;

use Sylius\CmsPlugin\Importer\ImporterInterface;

interface LegacyPageImporterInterface extends ImporterInterface
{
public const CODE_COLUMN = 'code';

public const SECTIONS_COLUMN = 'sections';

public const CHANNELS_COLUMN = 'channels';

public const PRODUCTS_COLUMN = 'products';

public const SLUG_COLUMN = 'slug__locale__';

public const NAME_COLUMN = 'name__locale__';

public const IMAGE_COLUMN = 'image__locale__';

public const META_KEYWORDS_COLUMN = 'meta_keywords__locale__';

public const META_DESCRIPTION_COLUMN = 'meta_description__locale__';

public const CONTENT_COLUMN = 'content__locale__';

public const NAME_WHEN_LINKED_COLUMN = 'name_when_linked__locale__';

public const DESCRIPTION_WHEN_LINKED_COLUMN = 'description_when_linked__locale__';
}
30 changes: 30 additions & 0 deletions src/Migrations/Version20240916100051.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Sylius\CmsPlugin\Migrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20240916100051 extends AbstractMigration
{
public function getDescription(): string
{
return 'This migration removes the sylius_cms_block_locales table.';
}

public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE sylius_cms_block_locales DROP FOREIGN KEY FK_49C0AACE559DFD1');
$this->addSql('ALTER TABLE sylius_cms_block_locales DROP FOREIGN KEY FK_49C0AACE9ED820C');
$this->addSql('DROP TABLE sylius_cms_block_locales');
}

public function down(Schema $schema): void
{
$this->addSql('CREATE TABLE sylius_cms_block_locales (block_id INT NOT NULL, locale_id INT NOT NULL, INDEX IDX_49C0AACE9ED820C (block_id), INDEX IDX_49C0AACE559DFD1 (locale_id), PRIMARY KEY(block_id, locale_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'\' ');
$this->addSql('ALTER TABLE sylius_cms_block_locales ADD CONSTRAINT FK_49C0AACE559DFD1 FOREIGN KEY (locale_id) REFERENCES sylius_locale (id) ON DELETE CASCADE');
$this->addSql('ALTER TABLE sylius_cms_block_locales ADD CONSTRAINT FK_49C0AACE9ED820C FOREIGN KEY (block_id) REFERENCES sylius_cms_block (id) ON DELETE CASCADE');
}
}
19 changes: 0 additions & 19 deletions src/Resolver/BlockResourceResolver.php
Original file line number Diff line number Diff line change
@@ -8,9 +8,6 @@
use Sylius\CmsPlugin\Entity\BlockInterface;
use Sylius\CmsPlugin\Repository\BlockRepositoryInterface;
use Sylius\Component\Channel\Context\ChannelContextInterface;
use Sylius\Component\Locale\Context\LocaleContextInterface;
use Sylius\Component\Locale\Model\LocaleInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Webmozart\Assert\Assert;

final class BlockResourceResolver implements BlockResourceResolverInterface
@@ -19,8 +16,6 @@ public function __construct(
private BlockRepositoryInterface $blockRepository,
private LoggerInterface $logger,
private ChannelContextInterface $channelContext,
private LocaleContextInterface $localeContext,
private RepositoryInterface $localeRepository,
) {
}

@@ -39,20 +34,6 @@ public function findOrLog(string $code): ?BlockInterface
return null;
}

/** @var LocaleInterface $locale */
$locale = $this->localeRepository->findOneBy(['code' => $this->localeContext->getLocaleCode()]);
Assert::notNull($locale);

if (false === $block->hasLocale($locale) && 0 !== $block->getLocales()->count()) {
$this->logger->warning(sprintf(
'Block with "%s" code was found in the database, but it does not have "%s" locale.',
$code,
$this->localeContext->getLocaleCode(),
));

return null;
}

return $block;
}
}
1 change: 0 additions & 1 deletion src/Resources/config/api_resources/Block.xml
Original file line number Diff line number Diff line change
@@ -44,7 +44,6 @@
<property name="name" identifier="false" writable="false"/>
<property name="enabled" identifier="false" writable="false"/>
<property name="channels" identifier="false" writable="false"/>
<property name="locales" identifier="false" writable="false"/>
<property name="collections" identifier="false" writable="false"/>
<property name="products" identifier="false" writable="false"/>
<property name="taxons" identifier="false" writable="false"/>
11 changes: 0 additions & 11 deletions src/Resources/config/doctrine/Block.orm.xml
Original file line number Diff line number Diff line change
@@ -38,17 +38,6 @@
</order-by>
</one-to-many>

<many-to-many field="locales" target-entity="Sylius\Component\Locale\Model\LocaleInterface">
<join-table name="sylius_cms_block_locales">
<join-columns>
<join-column name="block_id" referenced-column-name="id" nullable="false" on-delete="CASCADE" />
</join-columns>
<inverse-join-columns>
<join-column name="locale_id" referenced-column-name="id" nullable="false" on-delete="CASCADE" />
</inverse-join-columns>
</join-table>
</many-to-many>

<many-to-many field="products" target-entity="Sylius\Component\Core\Model\ProductInterface">
<join-table name="sylius_cms_block_products">
<join-columns>
3 changes: 0 additions & 3 deletions src/Resources/config/serialization/Block.xml
Original file line number Diff line number Diff line change
@@ -23,9 +23,6 @@
<attribute name="channels">
<group>sylius_cms:block:read:show</group>
</attribute>
<attribute name="locales">
<group>sylius_cms:block:read:show</group>
</attribute>
<attribute name="collections">
<group>sylius_cms:block:read:show</group>
</attribute>
1 change: 0 additions & 1 deletion src/Resources/config/services/fixture.xml
Original file line number Diff line number Diff line change
@@ -34,7 +34,6 @@
<argument type="service" id="sylius_cms.repository.block" />
<argument type="service" id="sylius_cms.assigner.collections" />
<argument type="service" id="sylius_cms.assigner.channels" />
<argument type="service" id="sylius_cms.assigner.locales" />
<argument type="service" id="sylius_cms.assigner.products" />
<argument type="service" id="sylius_cms.assigner.taxons" />
<argument type="service" id="sylius_cms.assigner.products_in_taxons" />
28 changes: 24 additions & 4 deletions src/Resources/config/services/importer.xml
Original file line number Diff line number Diff line change
@@ -13,20 +13,19 @@
<argument type="service" id="sylius_cms.resolver.importer_channels" />
<argument type="service" id="validator" />
<argument type="service" id="doctrine.orm.entity_manager" />
<tag name="cms_plugin.importer" />
<tag name="sylius_cms.importer" />
</service>

<service id="sylius_cms.importer.block" class="Sylius\CmsPlugin\Importer\BlockImporter">
<argument type="service" id="sylius_cms.resolver.resource.block" />
<argument type="service" id="sylius_cms.resolver.importer_collections" />
<argument type="service" id="sylius_cms.resolver.importer_channels" />
<argument type="service" id="sylius_cms.resolver.importer_locales" />
<argument type="service" id="sylius_cms.resolver.importer_products" />
<argument type="service" id="sylius_cms.resolver.importer_taxons" />
<argument type="service" id="sylius_cms.resolver.importer_products_in_taxons" />
<argument type="service" id="validator" />
<argument type="service" id="sylius_cms.repository.block" />
<tag name="cms_plugin.importer" />
<tag name="sylius_cms.importer" />
</service>

<service id="sylius_cms.importer.media" class="Sylius\CmsPlugin\Importer\MediaImporter">
@@ -35,7 +34,28 @@
<argument type="service" id="sylius_cms.resolver.importer_collections" />
<argument type="service" id="validator" />
<argument type="service" id="sylius_cms.repository.media" />
<tag name="cms_plugin.importer" />
<tag name="sylius_cms.importer" />
</service>

<service id="sylius_cms.importer.page.legacy" class="Sylius\CmsPlugin\Importer\Legacy\LegacyPageImporter">
<argument type="service" id="sylius_cms.resolver.resource.page" />
<argument type="service" id="sylius.context.locale" />
<argument type="service" id="sylius_cms.resolver.importer_collections" />
<argument type="service" id="sylius_cms.resolver.importer_channels" />
<argument type="service" id="doctrine.orm.entity_manager" />
<argument type="service" id="sylius.repository.locale" />
<argument type="service" id="validator" />
<tag name="sylius_cms.importer" />
</service>

<service id="sylius_cms.importer.block.legacy" class="Sylius\CmsPlugin\Importer\Legacy\LegacyBlockImporter">
<argument type="service" id="sylius_cms.resolver.resource.block" />
<argument type="service" id="sylius_cms.resolver.importer_collections" />
<argument type="service" id="sylius_cms.resolver.importer_channels" />
<argument type="service" id="sylius_cms.repository.block" />
<argument type="service" id="sylius.repository.locale" />
<argument type="service" id="validator" />
<tag name="sylius_cms.importer" />
</service>
</services>
</container>
2 changes: 0 additions & 2 deletions src/Resources/config/services/resolver.xml
Original file line number Diff line number Diff line change
@@ -32,8 +32,6 @@
<argument type="service" id="sylius_cms.repository.block" />
<argument type="service" id="logger" />
<argument type="service" id="sylius.context.channel" />
<argument type="service" id="sylius.context.locale" />
<argument type="service" id="sylius.repository.locale" />
</service>

<service id="sylius_cms.resolver.collection_resource" class="Sylius\CmsPlugin\Resolver\CollectionResourceResolver" public="true">
1 change: 0 additions & 1 deletion src/Resources/views/Block/Crud/_form.html.twig
Original file line number Diff line number Diff line change
@@ -12,7 +12,6 @@
{{ form_row(form.code) }}
{{ form_row(form.enabled) }}
{{ form_row(form.channels) }}
{{ form_row(form.locales) }}
{{ form_row(form.collections) }}
<a
href="#"
6 changes: 0 additions & 6 deletions tests/Application/config/packages/sylius_cms_plugin.yaml
Original file line number Diff line number Diff line change
@@ -38,8 +38,6 @@ sylius_fixtures:
name: "Homepage textarea"
channels:
- "FASHION_WEB"
locales:
- "en_US"
content_elements:
en_US:
heading:
@@ -59,8 +57,6 @@ sylius_fixtures:
name: "Homepage products carousel"
channels:
- "FASHION_WEB"
locales:
- "en_US"
content_elements:
en_US:
heading:
@@ -81,8 +77,6 @@ sylius_fixtures:
name: "Homepage products carousel by Taxon"
channels:
- "FASHION_WEB"
locales:
- "en_US"
content_elements:
en_US:
heading:
6 changes: 0 additions & 6 deletions tests/Functional/DataFixtures/ORM/Api/BlockTest/block.yml
Original file line number Diff line number Diff line change
@@ -80,8 +80,6 @@ Sylius\CmsPlugin\Entity\Block:
- '@collection1'
channels:
- '@channel'
locales:
- '@locale'
block2:
code: 'block2-code'
name: 'block2-name'
@@ -90,8 +88,6 @@ Sylius\CmsPlugin\Entity\Block:
- '@collection2'
channels:
- '@channel'
locales:
- '@locale'
block3:
code: 'block3-code'
name: 'block3-name'
@@ -100,8 +96,6 @@ Sylius\CmsPlugin\Entity\Block:
- '@collection3'
channels:
- '@channel'
locales:
- '@locale'
Sylius\CmsPlugin\Entity\Collection:
collection1:
code: 'collection1-code'
Original file line number Diff line number Diff line change
@@ -12,9 +12,6 @@
"channels": [
"/api/v2/shop/channels/code"
],
"locales": [
"/api/v2/shop/locales/@string@"
],
"contentElements": [],
"products": [],
"taxons": [],

0 comments on commit 4b028d9

Please sign in to comment.