Skip to content

Commit

Permalink
add element hash to headless stack (#226)
Browse files Browse the repository at this point in the history
  • Loading branch information
solverat authored Aug 15, 2024
1 parent eefdbfd commit 6b352ae
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 22 deletions.
3 changes: 3 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Upgrade Notes

## 5.2.0
- [NEW FEATURE] Add element hash to headless stack

## 5.1.2
- [BUGFIX] Enriched injected JS `toolbox-wysiwyg-document-style.js` with toolbox document id param [#223](https://github.com/dachcom-digital/pimcore-toolbox/issues/223)

Expand Down
6 changes: 4 additions & 2 deletions src/Document/Editable/EditableJsonSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ final class EditableJsonSubscriber implements EventSubscriberInterface
protected const ELEMENTS_IDENTIFIER = 'elements';
protected const ELEMENT_TYPE_IDENTIFIER = 'elementType';
protected const ELEMENT_SUB_TYPE_IDENTIFIER = 'elementSubType';
protected const ELEMENT_HASH = 'elementHash';
protected const ELEMENT_DATA_IDENTIFIER = 'elementContext';

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

public function onHeadlessElementAdd(HeadlessElementEvent $event): void
{
$this->jsonEditables[$event->getElementNamespace()] = [$event->getElementType(), $event->getElementSubType(), $event->getData()];
$this->jsonEditables[$event->getElementNamespace()] = [$event->getElementType(), $event->getElementSubType(), $event->getElementHash(), $event->getData()];
}

public function getJsonEditables(): array
Expand Down Expand Up @@ -59,7 +60,8 @@ private function convertNestedArray($flatArray): array

$currentArray[self::ELEMENT_TYPE_IDENTIFIER] = $value[0];
$currentArray[self::ELEMENT_SUB_TYPE_IDENTIFIER] = $value[1];
$currentArray[self::ELEMENT_DATA_IDENTIFIER] = $value[2];
$currentArray[self::ELEMENT_HASH] = $value[2];
$currentArray[self::ELEMENT_DATA_IDENTIFIER] = $value[3];
}

/** @phpstan-ignore-next-line */
Expand Down
28 changes: 28 additions & 0 deletions src/Document/Editable/EditableWorker.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public function processBrick(HeadlessResponse $data, AreabrickInterface $areabri
$this->dispatch([
'elementType' => $data->getType(),
'elementSubType' => $areabrick->getId(),
'elementHash' => $this->buildBrickHash(),
'elementNamespace' => $this->buildBrickNamespace(),
'data' => $this->processBrickData($data, $areabrick->getId())
]);
Expand All @@ -40,11 +41,38 @@ public function processEditable(HeadlessResponse $data, Editable $editable): voi
$this->dispatch([
'elementType' => $data->getType(),
'elementSubType' => $editable->getType(),
'elementHash' => $this->buildEditableHash($editable),
'elementNamespace' => $this->buildEditableNamespace($editable),
'data' => $this->processEditableData($data)
]);
}

public function processVirtualElement(string $type, string $subType, string $hash, string $namespace): void
{
$this->dispatch([
'elementType' => $type,
'elementSubType' => $subType,
'elementHash' => $hash,
'elementNamespace' => $namespace,
'data' => []
]);
}

public function buildBrickHash(): string
{
return hash('xxh3', sprintf('element_hash_%s', str_replace([':', '.'], '_', $this->buildBrickNamespace())));
}

public function buildEditableHash(Editable $editable): string
{
return hash('xxh3', sprintf('element_hash_%s', str_replace([':', '.'], '_', $editable->getName())));
}

public function buildBlockHash(string $blockName, int $blockIndex): string
{
return hash('xxh3', sprintf('element_hash_%s_%d', $blockName, $blockIndex));
}

private function dispatch(array $arguments): void
{
$this->eventDispatcher->dispatch(
Expand Down
73 changes: 54 additions & 19 deletions src/Document/Editable/HeadlessEditableRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,24 @@ public function __construct(

public function renderBrickWithWrapper(array $contentBlocks): string
{
return sprintf('<div class="inline-config-area">%s</div>', implode(PHP_EOL, $contentBlocks));
$brickHash = $this->editableWorker->buildBrickHash();

return sprintf(
'<div class="inline-config-area" data-headless-element-hash="%s">%s</div>',
$brickHash,
implode(PHP_EOL, $contentBlocks)
);
}

public function renderStandaloneEditableWithWrapper(string $contentBlock): string
public function renderStandaloneEditableWithWrapper(string $contentBlock, Editable $editable): string
{
return sprintf('<div class="inline-config-area">%s</div>', $contentBlock);
$editableHash = $this->editableWorker->buildEditableHash($editable);

return sprintf(
'<div class="inline-config-area" data-headless-element-hash="%s">%s</div>',
$editableHash,
$contentBlock
);
}

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

private function buildStandardEditable(HeadlessEditableInfo $headlessEditableInfo): Editable|string|array
{
return $this->processEditable($headlessEditableInfo);
return $this->processEditable($headlessEditableInfo, $this->getEditable($headlessEditableInfo));
}

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

$areaBlockDataResponse = null;
$editable = $this->getEditable($headlessEditableInfo);

ob_start();

echo $this->processEditable($headlessColumnEditableInfo, true);
echo $this->processEditable($headlessColumnEditableInfo, $editable, true);

if ($editMode === false) {
$areaBlockDataResponse = $this->processEditable($headlessColumnEditableInfo);
$areaBlockDataResponse = $this->processEditable($headlessColumnEditableInfo, $editable);
}

$areaBlockHtmlResponse = ob_get_clean();
Expand All @@ -100,13 +113,14 @@ private function buildAreaEditable(HeadlessEditableInfo $headlessEditableInfo):
{
$areaDataResponse = '';
$editMode = $headlessEditableInfo->isEditMode();
$editable = $this->getEditable($headlessEditableInfo);

ob_start();

echo $this->processEditable($headlessEditableInfo, true);
echo $this->processEditable($headlessEditableInfo, $editable, true);

if ($editMode === false) {
$areaDataResponse = $this->processEditable($headlessEditableInfo);
$areaDataResponse = $this->processEditable($headlessEditableInfo, $editable);
}

$areaHtmlResponse = ob_get_clean();
Expand All @@ -118,13 +132,14 @@ private function buildAreaBlockEditable(HeadlessEditableInfo $headlessEditableIn
{
$areaBlockDataResponse = '';
$editMode = $headlessEditableInfo->isEditMode();
$editable = $this->getEditable($headlessEditableInfo);

ob_start();

echo $this->processEditable($headlessEditableInfo, true);
echo $this->processEditable($headlessEditableInfo, $editable, true);

if ($editMode === false) {
$areaBlockDataResponse = $this->processEditable($headlessEditableInfo);
$areaBlockDataResponse = $this->processEditable($headlessEditableInfo, $editable);
}

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

foreach ($blockEditable->getIterator() as $blockIndex) {

$blockHash = $this->editableWorker->buildBlockHash($headlessEditableInfo->getName(), $blockIndex);
$blockNamespace = sprintf('%s:%s', $headlessEditableInfo->getName(), $blockIndex);

if ($editMode === true) {
echo sprintf('<a data-headless-element-hash="%s"></a>', $blockHash);
}

$this->editableWorker->processVirtualElement(HeadlessResponse::TYPE_EDITABLE, 'block', $blockHash, $blockNamespace);

foreach ($headlessEditableInfo->getChildren() as $childHeadlessEditableInfo) {

$editable = $this->getEditable($childHeadlessEditableInfo);

ob_start();

echo $this->processEditable($childHeadlessEditableInfo, true);
echo $this->processEditable($childHeadlessEditableInfo, $editable, true);

$renderedBlockEditable = ob_get_clean();

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

if ($editMode === false) {
$data[] = $this->processEditable($childHeadlessEditableInfo);
$data[] = $this->processEditable($childHeadlessEditableInfo, $editable);
}
}
}
Expand All @@ -172,18 +199,12 @@ private function buildBlockEditable(HeadlessEditableInfo $headlessEditableInfo):
return $editMode ? $areaBlockHtmlResponse : $data;
}

private function processEditable(HeadlessEditableInfo $headlessEditableInfo, bool $forceRendering = false): mixed
private function processEditable(HeadlessEditableInfo $headlessEditableInfo, Editable $editable, bool $forceRendering = false): mixed
{
$editMode = $headlessEditableInfo->isEditMode();
$type = $headlessEditableInfo->getType();
$name = $headlessEditableInfo->getName();
$config = $headlessEditableInfo->getConfig();
$document = $headlessEditableInfo->getDocument();
$isSimple = !$headlessEditableInfo->isBlockEditable();

/** @var Editable $editable */
$editable = $this->editableRenderer->getEditable($document, $type, $name, $config, $editMode);

if ($headlessEditableInfo->isStandAlone() === true) {

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

return '';
}

public function getEditable(HeadlessEditableInfo $headlessEditableInfo): Editable
{
$editMode = $headlessEditableInfo->isEditMode();
$type = $headlessEditableInfo->getType();
$name = $headlessEditableInfo->getName();
$config = $headlessEditableInfo->getConfig();
$document = $headlessEditableInfo->getDocument();

/** @var Editable $editable */
$editable = $this->editableRenderer->getEditable($document, $type, $name, $config, $editMode);

return $editable;
}
}
6 changes: 6 additions & 0 deletions src/Event/HeadlessElementEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public function __construct(
protected array $data,
protected string $elementType,
protected string $elementSubType,
protected ?string $elementHash,
protected string $elementNamespace
) {
}
Expand All @@ -29,6 +30,11 @@ public function getElementSubType(): string
return $this->elementSubType;
}

public function getElementHash(): ?string
{
return $this->elementHash;
}

public function getElementNamespace(): string
{
return $this->elementNamespace;
Expand Down
4 changes: 3 additions & 1 deletion src/HeadlessDocument/HeadlessDocumentResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ private function buildEditModeOutput(Document $document, string $headlessDocumen

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

if (in_array($headlessInfo->getType(), ['areablock', 'area'])) {
// will be rendered within brick process workflow
Expand All @@ -76,7 +77,8 @@ private function buildEditModeOutput(Document $document, string $headlessDocumen
$this->headlessEditableRenderer->renderEditableWithWrapper($item['type'], [
'item' => $item,
'editable' => $renderedEditable
])
]),
$editable
);
}

Expand Down

0 comments on commit 6b352ae

Please sign in to comment.