Skip to content

Commit 0ec5562

Browse files
author
Aleksander Laurowski
committed
FFWEB-2443 add layout column to cms export
1 parent 835527c commit 0ec5562

4 files changed

Lines changed: 270 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Changelog
2+
## [Unreleased]
3+
### Add
4+
- Export
5+
- Added new field provider `Omikron\FactFinder\Shopware6\Export\Field\Layout` applicable to CMS Export
6+
27
## [v3.0.1] - 2022.03.10
3-
48
### Fix
59
- `Omikron\FactFinder\Shopware6\Subscriber\CategoryView`
610
- fix category path is not encoded correctly

spec/Export/Field/LayoutSpec.php

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace spec\Omikron\FactFinder\Shopware6\Export\Field;
6+
7+
use Omikron\FactFinder\Shopware6\Export\Filter\TextFilter;
8+
use PhpSpec\ObjectBehavior;
9+
use Shopware\Core\Content\Category\CategoryEntity;
10+
use Shopware\Core\Content\Cms\Aggregate\CmsBlock\CmsBlockCollection;
11+
use Shopware\Core\Content\Cms\Aggregate\CmsBlock\CmsBlockEntity;
12+
use Shopware\Core\Content\Cms\Aggregate\CmsSection\CmsSectionCollection;
13+
use Shopware\Core\Content\Cms\Aggregate\CmsSection\CmsSectionEntity;
14+
use Shopware\Core\Content\Cms\Aggregate\CmsSlot\CmsSlotCollection;
15+
use Shopware\Core\Content\Cms\Aggregate\CmsSlot\CmsSlotEntity;
16+
use Shopware\Core\Content\Cms\CmsPageEntity;
17+
18+
class LayoutSpec extends ObjectBehavior
19+
{
20+
function let(): void
21+
{
22+
$this->beConstructedWith(new TextFilter());
23+
}
24+
25+
function it_should_strip_html_tags(CategoryEntity $categoryEntity): void
26+
{
27+
$cmsPage = new CmsPageEntity();
28+
$cmsPage->setSections(
29+
new CmsSectionCollection(
30+
[
31+
'1' => $this->createSection(
32+
[
33+
'1' => $this->createBlock(
34+
[
35+
'1' => $this->createSlot(['content' => ['value' => '<h2>Lorem Ipsum </h2><p>Dolor sit amet</p>']]),
36+
]
37+
),
38+
]
39+
),
40+
]
41+
)
42+
);
43+
$categoryEntity->getCmsPage()->willReturn($cmsPage);
44+
$this->getValue($categoryEntity)->shouldReturn('Lorem Ipsum Dolor sit amet');
45+
}
46+
47+
function it_should_concatenate_values_from_all_slots_configs(CategoryEntity $categoryEntity): void
48+
{
49+
$cmsPage = new CmsPageEntity();
50+
$cmsPage->setSections(
51+
new CmsSectionCollection(
52+
[
53+
'1' => $this->createSection(
54+
[
55+
'1' => $this->createBlock(
56+
[
57+
'1' => $this->createSlot(['content' => ['value' => 'I am']]),
58+
], 1
59+
),
60+
],
61+
),
62+
'2' => $this->createSection(
63+
[
64+
'1' => $this->createBlock(
65+
[
66+
'1' => $this->createSlot(['content' => ['value' => 'concatenated']]),
67+
], 2
68+
),
69+
], 2
70+
),
71+
]
72+
)
73+
);
74+
$categoryEntity->getCmsPage()->willReturn($cmsPage);
75+
$this->getValue($categoryEntity)->shouldReturn('I am concatenated');
76+
}
77+
78+
function it_should_sort_output_by_position(CategoryEntity $categoryEntity): void
79+
{
80+
$cmsPage = new CmsPageEntity();
81+
$cmsPage->setSections(
82+
new CmsSectionCollection(
83+
[
84+
'1' => $this->createSection(
85+
[
86+
'1' => $this->createBlock(
87+
[
88+
'1' => $this->createSlot(['content' => ['value' => 'not']]),
89+
], 2
90+
),
91+
'2' => $this->createBlock(
92+
[
93+
'1' => $this->createSlot(['content' => ['value' => 'Yoda']]),
94+
],
95+
3
96+
),
97+
'3' => $this->createBlock(
98+
[
99+
'1' => $this->createSlot(['content' => ['value' => 'I am']]),
100+
], 1
101+
),
102+
]
103+
),
104+
]
105+
)
106+
);
107+
108+
$categoryEntity->getCmsPage()->willReturn($cmsPage);
109+
$this->getValue($categoryEntity)->shouldReturn('I am not Yoda');
110+
}
111+
112+
function it_should_not_throw_if_section_has_no_blocks(CategoryEntity $categoryEntity)
113+
{
114+
$cmsPage = new CmsPageEntity();
115+
$cmsPage->setSections(
116+
new CmsSectionCollection(
117+
[
118+
'1' => $this->createSection(),
119+
'2' => $this->createSection(),
120+
]
121+
)
122+
);
123+
$categoryEntity->getCmsPage()->willReturn($cmsPage);
124+
$this->getValue($categoryEntity)->shouldReturn('');
125+
}
126+
127+
function it_should_not_throw_if_category_has_no_layout_assigned(CategoryEntity $categoryEntity)
128+
{
129+
$categoryEntity->getCmsPage()->willReturn(null);
130+
$this->getValue($categoryEntity)->shouldReturn('');
131+
}
132+
133+
function it_should_not_throw_if_block_has_no_slots(CategoryEntity $categoryEntity)
134+
{
135+
$cmsPage = new CmsPageEntity();
136+
$cmsPage->setSections(
137+
new CmsSectionCollection(
138+
[
139+
'1' => $this->createSection(
140+
[
141+
'1' => $this->createBlock(),
142+
'2' => $this->createBlock(),
143+
]
144+
)
145+
]
146+
)
147+
);
148+
149+
$categoryEntity->getCmsPage()->willReturn($cmsPage);
150+
$this->getValue($categoryEntity)->shouldReturn('');
151+
}
152+
153+
private function createSection(array $blocks = [], int $position = 1): CmsSectionEntity
154+
{
155+
$section = new CmsSectionEntity();
156+
$section->setId(uniqid());
157+
$section->setPosition($position);
158+
if (count($blocks)) {
159+
$section->setBlocks(new CmsBlockCollection($blocks));
160+
}
161+
return $section;
162+
}
163+
164+
private function createBlock(array $slots = [], int $position = 1): CmsBlockEntity
165+
{
166+
$block = new CmsBlockEntity();
167+
$block->setId(uniqid());
168+
$block->setPosition($position);
169+
if (count($slots)) {
170+
$block->setSlots(new CmsSlotCollection($slots));
171+
}
172+
return $block;
173+
}
174+
175+
private function createSlot(array $config): CmsSlotEntity
176+
{
177+
$slot = new CmsSlotEntity();
178+
$slot->setId(uniqid());
179+
$slot->setSlot(uniqid('slot-'));
180+
$slot->setConfig($config);
181+
return $slot;
182+
}
183+
}

src/Export/ExportCategories.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ private function getCriteria(int $batchSize): Criteria
5454
$criteria->addAssociation('customFields');
5555
$criteria->addAssociation('media');
5656
$criteria->addAssociation('seoUrls');
57+
$criteria->addAssociation('cmsPage.sections');
58+
$criteria->addAssociation('cmsPage.sections.blocks');
59+
$criteria->addAssociation('cmsPage.sections.blocks.slots');
60+
$criteria->addAssociation('slotConfig');
5761
foreach ($this->customAssociations as $association) {
5862
$criteria->addAssociation($association);
5963
}

src/Export/Field/Layout.php

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Omikron\FactFinder\Shopware6\Export\Field;
6+
7+
use Omikron\FactFinder\Shopware6\Export\Filter\TextFilter;
8+
use Shopware\Core\Content\Category\CategoryEntity;
9+
use Shopware\Core\Content\Cms\Aggregate\CmsBlock\CmsBlockEntity;
10+
use Shopware\Core\Content\Cms\Aggregate\CmsSection\CmsSectionEntity;
11+
use Shopware\Core\Content\Cms\Aggregate\CmsSlot\CmsSlotEntity;
12+
use Shopware\Core\Framework\DataAbstractionLayer\Entity;
13+
use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection;
14+
use function Omikron\FactFinder\Shopware6\Internal\Utils\flatMap;
15+
use function Omikron\FactFinder\Shopware6\Internal\Utils\safeGetByName;
16+
17+
class Layout implements FieldInterface
18+
{
19+
private TextFilter $textFilter;
20+
21+
public function __construct(TextFilter $textFilter)
22+
{
23+
$this->textFilter = $textFilter;
24+
}
25+
26+
public function getName(): string
27+
{
28+
return 'Layout';
29+
}
30+
31+
/**
32+
* @param CategoryEntity $entity
33+
*
34+
* @return string
35+
*/
36+
public function getValue(Entity $entity): string
37+
{
38+
$cmsPage = $entity->getCmsPage();
39+
if (!$cmsPage) {
40+
return '';
41+
}
42+
43+
$layout = array_map(
44+
fn (CmsSlotEntity $slot) => safeGetByName(safeGetByName($slot->getConfig(), 'content'), 'value'),
45+
flatMap(
46+
fn (CmsBlockEntity $block): array => $this->toValues($block->getSlots()),
47+
flatMap(
48+
fn (CmsSectionEntity $section): array => $this->toValues($section->getBlocks()),
49+
$this->toValues($cmsPage->getSections())
50+
)
51+
)
52+
);
53+
54+
return $this->textFilter->filterValue(implode(' ', array_filter($layout)));
55+
}
56+
57+
public function getCompatibleEntityTypes(): array
58+
{
59+
return [CategoryEntity::class];
60+
}
61+
62+
private function toValues(?EntityCollection $collection): array
63+
{
64+
if (!$collection) {
65+
return [];
66+
}
67+
/**
68+
* @param CmsBlockEntity|CmsSectionEntity $current
69+
* @param CmsBlockEntity|CmsSectionEntity $next
70+
*
71+
* @return bool
72+
*/
73+
$sortByPosition = fn ($current, $next): bool => !method_exists($current, 'getPosition') || $current->getPosition() > $next->getPosition();
74+
$collection->sort($sortByPosition);
75+
76+
return array_values($collection->getElements());
77+
}
78+
}

0 commit comments

Comments
 (0)