vendor/ibexa/fieldtype-page/src/lib/Event/Subscriber/AddMissingAttributesOnLoadSubscriber.php line 50

Open in your IDE?
  1. <?php
  2. /**
  3. * @copyright Copyright (C) Ibexa AS. All rights reserved.
  4. * @license For full copyright and license information view LICENSE file distributed with this source code.
  5. */
  6. declare(strict_types=1);
  7. namespace Ibexa\FieldTypePage\Event\Subscriber;
  8. use Ibexa\Contracts\FieldTypePage\FieldType\LandingPage\Model\Attribute;
  9. use Ibexa\Contracts\FieldTypePage\FieldType\LandingPage\Model\BlockValue;
  10. use Ibexa\Contracts\FieldTypePage\FieldType\Page\Block\Definition\BlockDefinition;
  11. use Ibexa\FieldTypePage\Event\PageEvents;
  12. use Ibexa\FieldTypePage\Event\PageFromPersistenceEvent;
  13. use Ibexa\FieldTypePage\FieldType\Page\Block\Definition\BlockDefinitionFactoryInterface;
  14. use Ibexa\FieldTypePage\Serializer\AttributeSerializationDispatcher;
  15. use Ramsey\Uuid\Uuid;
  16. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  17. class AddMissingAttributesOnLoadSubscriber implements EventSubscriberInterface
  18. {
  19. /** @var \Ibexa\FieldTypePage\FieldType\Page\Block\Definition\BlockDefinitionFactoryInterface */
  20. private $blockDefinitionFactory;
  21. /** @var \Ibexa\FieldTypePage\Serializer\AttributeSerializationDispatcher */
  22. private $attributeSerializationDispatcher;
  23. public function __construct(
  24. BlockDefinitionFactoryInterface $blockDefinitionFactory,
  25. AttributeSerializationDispatcher $attributeSerializationDispatcher
  26. ) {
  27. $this->blockDefinitionFactory = $blockDefinitionFactory;
  28. $this->attributeSerializationDispatcher = $attributeSerializationDispatcher;
  29. }
  30. /**
  31. * {@inheritdoc}
  32. */
  33. public static function getSubscribedEvents(): array
  34. {
  35. return [
  36. PageEvents::PERSISTENCE_FROM => ['onLoadFromPersistence', 100],
  37. ];
  38. }
  39. /**
  40. * @param \Ibexa\FieldTypePage\Event\PageFromPersistenceEvent $event
  41. */
  42. public function onLoadFromPersistence(PageFromPersistenceEvent $event): void
  43. {
  44. $value = $event->getValue();
  45. $page = $value->getPage();
  46. // local cache to save roundtrips to redis/fs cache
  47. $visitedBlockDefinitions = [];
  48. foreach ($page->getZones() as $zone) {
  49. foreach ($zone->getBlocks() as $block) {
  50. $type = $block->getType();
  51. $blockDefinition = $this->getBlockDefinition($type, $visitedBlockDefinitions);
  52. $visitedBlockDefinitions[$type] = $blockDefinition;
  53. $block->setAttributes(
  54. array_merge($block->getAttributes(), $this->getMissingAttributes($block, $blockDefinition))
  55. );
  56. }
  57. }
  58. $event->setValue($value);
  59. }
  60. /**
  61. * @return \Ibexa\Contracts\FieldTypePage\FieldType\LandingPage\Model\Attribute[]
  62. */
  63. private function getMissingAttributes(BlockValue $block, BlockDefinition $blockDefinition): array
  64. {
  65. $missingAttributes = [];
  66. foreach ($blockDefinition->getAttributes() as $attributeDefinition) {
  67. if ($this->hasAttribute($block, $attributeDefinition->getIdentifier())) {
  68. continue;
  69. }
  70. $deserializedValue = $this->attributeSerializationDispatcher->deserialize(
  71. $block,
  72. $attributeDefinition->getIdentifier(),
  73. $attributeDefinition->getValue()
  74. );
  75. $missingAttributes[] = new Attribute(
  76. Uuid::uuid1()->toString(),
  77. $attributeDefinition->getIdentifier(),
  78. $deserializedValue
  79. );
  80. }
  81. return $missingAttributes;
  82. }
  83. /**
  84. * @param \Ibexa\Contracts\FieldTypePage\FieldType\LandingPage\Model\BlockValue $blockValue
  85. * @param string $attributeIdentifier
  86. *
  87. * @return bool
  88. */
  89. private function hasAttribute(BlockValue $blockValue, string $attributeIdentifier): bool
  90. {
  91. foreach ($blockValue->getAttributes() as $attribute) {
  92. if ($attribute->getName() === $attributeIdentifier) {
  93. return true;
  94. }
  95. }
  96. return false;
  97. }
  98. private function getBlockDefinition(string $type, array $visitedBlockDefinitions): BlockDefinition
  99. {
  100. return $visitedBlockDefinitions[$type] ?? $this->blockDefinitionFactory->getBlockDefinition($type);
  101. }
  102. }
  103. class_alias(AddMissingAttributesOnLoadSubscriber::class, 'EzSystems\EzPlatformPageFieldType\Event\Subscriber\AddMissingAttributesOnLoadSubscriber');