Skip to content

Commit 6b352ae

Browse files
authored
add element hash to headless stack (#226)
1 parent eefdbfd commit 6b352ae

File tree

6 files changed

+98
-22
lines changed

6 files changed

+98
-22
lines changed

UPGRADE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Upgrade Notes
22

3+
## 5.2.0
4+
- [NEW FEATURE] Add element hash to headless stack
5+
36
## 5.1.2
47
- [BUGFIX] Enriched injected JS `toolbox-wysiwyg-document-style.js` with toolbox document id param [#223](https://github.com/dachcom-digital/pimcore-toolbox/issues/223)
58

src/Document/Editable/EditableJsonSubscriber.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ final class EditableJsonSubscriber implements EventSubscriberInterface
1313
protected const ELEMENTS_IDENTIFIER = 'elements';
1414
protected const ELEMENT_TYPE_IDENTIFIER = 'elementType';
1515
protected const ELEMENT_SUB_TYPE_IDENTIFIER = 'elementSubType';
16+
protected const ELEMENT_HASH = 'elementHash';
1617
protected const ELEMENT_DATA_IDENTIFIER = 'elementContext';
1718

1819
protected array $jsonEditables = [];
@@ -26,7 +27,7 @@ public static function getSubscribedEvents(): array
2627

2728
public function onHeadlessElementAdd(HeadlessElementEvent $event): void
2829
{
29-
$this->jsonEditables[$event->getElementNamespace()] = [$event->getElementType(), $event->getElementSubType(), $event->getData()];
30+
$this->jsonEditables[$event->getElementNamespace()] = [$event->getElementType(), $event->getElementSubType(), $event->getElementHash(), $event->getData()];
3031
}
3132

3233
public function getJsonEditables(): array
@@ -59,7 +60,8 @@ private function convertNestedArray($flatArray): array
5960

6061
$currentArray[self::ELEMENT_TYPE_IDENTIFIER] = $value[0];
6162
$currentArray[self::ELEMENT_SUB_TYPE_IDENTIFIER] = $value[1];
62-
$currentArray[self::ELEMENT_DATA_IDENTIFIER] = $value[2];
63+
$currentArray[self::ELEMENT_HASH] = $value[2];
64+
$currentArray[self::ELEMENT_DATA_IDENTIFIER] = $value[3];
6365
}
6466

6567
/** @phpstan-ignore-next-line */

src/Document/Editable/EditableWorker.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public function processBrick(HeadlessResponse $data, AreabrickInterface $areabri
3030
$this->dispatch([
3131
'elementType' => $data->getType(),
3232
'elementSubType' => $areabrick->getId(),
33+
'elementHash' => $this->buildBrickHash(),
3334
'elementNamespace' => $this->buildBrickNamespace(),
3435
'data' => $this->processBrickData($data, $areabrick->getId())
3536
]);
@@ -40,11 +41,38 @@ public function processEditable(HeadlessResponse $data, Editable $editable): voi
4041
$this->dispatch([
4142
'elementType' => $data->getType(),
4243
'elementSubType' => $editable->getType(),
44+
'elementHash' => $this->buildEditableHash($editable),
4345
'elementNamespace' => $this->buildEditableNamespace($editable),
4446
'data' => $this->processEditableData($data)
4547
]);
4648
}
4749

50+
public function processVirtualElement(string $type, string $subType, string $hash, string $namespace): void
51+
{
52+
$this->dispatch([
53+
'elementType' => $type,
54+
'elementSubType' => $subType,
55+
'elementHash' => $hash,
56+
'elementNamespace' => $namespace,
57+
'data' => []
58+
]);
59+
}
60+
61+
public function buildBrickHash(): string
62+
{
63+
return hash('xxh3', sprintf('element_hash_%s', str_replace([':', '.'], '_', $this->buildBrickNamespace())));
64+
}
65+
66+
public function buildEditableHash(Editable $editable): string
67+
{
68+
return hash('xxh3', sprintf('element_hash_%s', str_replace([':', '.'], '_', $editable->getName())));
69+
}
70+
71+
public function buildBlockHash(string $blockName, int $blockIndex): string
72+
{
73+
return hash('xxh3', sprintf('element_hash_%s_%d', $blockName, $blockIndex));
74+
}
75+
4876
private function dispatch(array $arguments): void
4977
{
5078
$this->eventDispatcher->dispatch(

src/Document/Editable/HeadlessEditableRenderer.php

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,24 @@ public function __construct(
2121

2222
public function renderBrickWithWrapper(array $contentBlocks): string
2323
{
24-
return sprintf('<div class="inline-config-area">%s</div>', implode(PHP_EOL, $contentBlocks));
24+
$brickHash = $this->editableWorker->buildBrickHash();
25+
26+
return sprintf(
27+
'<div class="inline-config-area" data-headless-element-hash="%s">%s</div>',
28+
$brickHash,
29+
implode(PHP_EOL, $contentBlocks)
30+
);
2531
}
2632

27-
public function renderStandaloneEditableWithWrapper(string $contentBlock): string
33+
public function renderStandaloneEditableWithWrapper(string $contentBlock, Editable $editable): string
2834
{
29-
return sprintf('<div class="inline-config-area">%s</div>', $contentBlock);
35+
$editableHash = $this->editableWorker->buildEditableHash($editable);
36+
37+
return sprintf(
38+
'<div class="inline-config-area" data-headless-element-hash="%s">%s</div>',
39+
$editableHash,
40+
$contentBlock
41+
);
3042
}
3143

3244
public function renderEditableWithWrapper(string $type, array $viewParameters): string
@@ -52,7 +64,7 @@ public function buildEditable(HeadlessEditableInfo $headlessEditableInfo): Edita
5264

5365
private function buildStandardEditable(HeadlessEditableInfo $headlessEditableInfo): Editable|string|array
5466
{
55-
return $this->processEditable($headlessEditableInfo);
67+
return $this->processEditable($headlessEditableInfo, $this->getEditable($headlessEditableInfo));
5668
}
5769

5870
private function buildColumnEditable(HeadlessEditableInfo $headlessEditableInfo): string|array
@@ -72,13 +84,14 @@ private function buildColumnEditable(HeadlessEditableInfo $headlessEditableInfo)
7284
foreach ($headlessEditableInfo->getChildren() as $headlessColumnEditableInfo) {
7385

7486
$areaBlockDataResponse = null;
87+
$editable = $this->getEditable($headlessEditableInfo);
7588

7689
ob_start();
7790

78-
echo $this->processEditable($headlessColumnEditableInfo, true);
91+
echo $this->processEditable($headlessColumnEditableInfo, $editable, true);
7992

8093
if ($editMode === false) {
81-
$areaBlockDataResponse = $this->processEditable($headlessColumnEditableInfo);
94+
$areaBlockDataResponse = $this->processEditable($headlessColumnEditableInfo, $editable);
8295
}
8396

8497
$areaBlockHtmlResponse = ob_get_clean();
@@ -100,13 +113,14 @@ private function buildAreaEditable(HeadlessEditableInfo $headlessEditableInfo):
100113
{
101114
$areaDataResponse = '';
102115
$editMode = $headlessEditableInfo->isEditMode();
116+
$editable = $this->getEditable($headlessEditableInfo);
103117

104118
ob_start();
105119

106-
echo $this->processEditable($headlessEditableInfo, true);
120+
echo $this->processEditable($headlessEditableInfo, $editable, true);
107121

108122
if ($editMode === false) {
109-
$areaDataResponse = $this->processEditable($headlessEditableInfo);
123+
$areaDataResponse = $this->processEditable($headlessEditableInfo, $editable);
110124
}
111125

112126
$areaHtmlResponse = ob_get_clean();
@@ -118,13 +132,14 @@ private function buildAreaBlockEditable(HeadlessEditableInfo $headlessEditableIn
118132
{
119133
$areaBlockDataResponse = '';
120134
$editMode = $headlessEditableInfo->isEditMode();
135+
$editable = $this->getEditable($headlessEditableInfo);
121136

122137
ob_start();
123138

124-
echo $this->processEditable($headlessEditableInfo, true);
139+
echo $this->processEditable($headlessEditableInfo, $editable, true);
125140

126141
if ($editMode === false) {
127-
$areaBlockDataResponse = $this->processEditable($headlessEditableInfo);
142+
$areaBlockDataResponse = $this->processEditable($headlessEditableInfo, $editable);
128143
}
129144

130145
$areaBlockHtmlResponse = ob_get_clean();
@@ -145,11 +160,23 @@ private function buildBlockEditable(HeadlessEditableInfo $headlessEditableInfo):
145160
$blockEditable = $this->editableRenderer->getEditable($document, 'block', $headlessEditableInfo->getName(), $config, $headlessEditableInfo->isEditMode());
146161

147162
foreach ($blockEditable->getIterator() as $blockIndex) {
163+
164+
$blockHash = $this->editableWorker->buildBlockHash($headlessEditableInfo->getName(), $blockIndex);
165+
$blockNamespace = sprintf('%s:%s', $headlessEditableInfo->getName(), $blockIndex);
166+
167+
if ($editMode === true) {
168+
echo sprintf('<a data-headless-element-hash="%s"></a>', $blockHash);
169+
}
170+
171+
$this->editableWorker->processVirtualElement(HeadlessResponse::TYPE_EDITABLE, 'block', $blockHash, $blockNamespace);
172+
148173
foreach ($headlessEditableInfo->getChildren() as $childHeadlessEditableInfo) {
149174

175+
$editable = $this->getEditable($childHeadlessEditableInfo);
176+
150177
ob_start();
151178

152-
echo $this->processEditable($childHeadlessEditableInfo, true);
179+
echo $this->processEditable($childHeadlessEditableInfo, $editable, true);
153180

154181
$renderedBlockEditable = ob_get_clean();
155182

@@ -162,7 +189,7 @@ private function buildBlockEditable(HeadlessEditableInfo $headlessEditableInfo):
162189
]);
163190

164191
if ($editMode === false) {
165-
$data[] = $this->processEditable($childHeadlessEditableInfo);
192+
$data[] = $this->processEditable($childHeadlessEditableInfo, $editable);
166193
}
167194
}
168195
}
@@ -172,18 +199,12 @@ private function buildBlockEditable(HeadlessEditableInfo $headlessEditableInfo):
172199
return $editMode ? $areaBlockHtmlResponse : $data;
173200
}
174201

175-
private function processEditable(HeadlessEditableInfo $headlessEditableInfo, bool $forceRendering = false): mixed
202+
private function processEditable(HeadlessEditableInfo $headlessEditableInfo, Editable $editable, bool $forceRendering = false): mixed
176203
{
177204
$editMode = $headlessEditableInfo->isEditMode();
178205
$type = $headlessEditableInfo->getType();
179-
$name = $headlessEditableInfo->getName();
180-
$config = $headlessEditableInfo->getConfig();
181-
$document = $headlessEditableInfo->getDocument();
182206
$isSimple = !$headlessEditableInfo->isBlockEditable();
183207

184-
/** @var Editable $editable */
185-
$editable = $this->editableRenderer->getEditable($document, $type, $name, $config, $editMode);
186-
187208
if ($headlessEditableInfo->isStandAlone() === true) {
188209

189210
if ($editMode === false) {
@@ -217,4 +238,18 @@ private function processEditable(HeadlessEditableInfo $headlessEditableInfo, boo
217238

218239
return '';
219240
}
241+
242+
public function getEditable(HeadlessEditableInfo $headlessEditableInfo): Editable
243+
{
244+
$editMode = $headlessEditableInfo->isEditMode();
245+
$type = $headlessEditableInfo->getType();
246+
$name = $headlessEditableInfo->getName();
247+
$config = $headlessEditableInfo->getConfig();
248+
$document = $headlessEditableInfo->getDocument();
249+
250+
/** @var Editable $editable */
251+
$editable = $this->editableRenderer->getEditable($document, $type, $name, $config, $editMode);
252+
253+
return $editable;
254+
}
220255
}

src/Event/HeadlessElementEvent.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public function __construct(
1010
protected array $data,
1111
protected string $elementType,
1212
protected string $elementSubType,
13+
protected ?string $elementHash,
1314
protected string $elementNamespace
1415
) {
1516
}
@@ -29,6 +30,11 @@ public function getElementSubType(): string
2930
return $this->elementSubType;
3031
}
3132

33+
public function getElementHash(): ?string
34+
{
35+
return $this->elementHash;
36+
}
37+
3238
public function getElementNamespace(): string
3339
{
3440
return $this->elementNamespace;

src/HeadlessDocument/HeadlessDocumentResolver.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ private function buildEditModeOutput(Document $document, string $headlessDocumen
6767

6868
$headlessInfo = $this->editableInfoFactory->createViaEditable($document, $itemName, true, $item);
6969
$renderedEditable = $this->headlessEditableRenderer->buildEditable($headlessInfo);
70+
$editable = $this->headlessEditableRenderer->getEditable($headlessInfo);
7071

7172
if (in_array($headlessInfo->getType(), ['areablock', 'area'])) {
7273
// will be rendered within brick process workflow
@@ -76,7 +77,8 @@ private function buildEditModeOutput(Document $document, string $headlessDocumen
7677
$this->headlessEditableRenderer->renderEditableWithWrapper($item['type'], [
7778
'item' => $item,
7879
'editable' => $renderedEditable
79-
])
80+
]),
81+
$editable
8082
);
8183
}
8284

0 commit comments

Comments
 (0)