diff --git a/src/EventSubscriber/SetInlineBlockDependencyWithContextTranslation.php b/src/EventSubscriber/SetInlineBlockDependencyWithContextTranslation.php index ac010249c473b03e51380bb98d897c26eaed7b4f..f3976b87a3aa211515d9da2af507181c95ccd067 100644 --- a/src/EventSubscriber/SetInlineBlockDependencyWithContextTranslation.php +++ b/src/EventSubscriber/SetInlineBlockDependencyWithContextTranslation.php @@ -4,6 +4,12 @@ namespace Drupal\layout_builder_at\EventSubscriber; use Drupal\block_content\BlockContentInterface; use Drupal\layout_builder\EventSubscriber\SetInlineBlockDependency; +use Drupal\Core\Database\Connection; +use Drupal\Core\Entity\EntityRepositoryInterface; +use Drupal\Core\Routing\CurrentRouteMatch; +use Drupal\layout_builder\InlineBlockUsageInterface; +use Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface; +use Drupal\Core\Access\AccessibleInterface; /** * Takes over \Drupal\layout_builder\EventSubscriber\SetInlineBlockDependency @@ -11,25 +17,90 @@ use Drupal\layout_builder\EventSubscriber\SetInlineBlockDependency; */ class SetInlineBlockDependencyWithContextTranslation extends SetInlineBlockDependency { + /** + * The entity type manager. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected $entityTypeManager; + + /** + * Constructs SetInlineBlockDependency object. + * + * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository + * The entity repository. + * @param \Drupal\Core\Database\Connection $database + * The database connection. + * @param \Drupal\layout_builder\InlineBlockUsageInterface $usage + * The inline block usage service. + * @param \Drupal\layout_builder\SectionStorage\SectionStorageManagerInterface $section_storage_manager + * The section storage manager. + * @param \Drupal\Core\Routing\RouteMatchInterface|null $current_route_match + * The current route match service. + */ + public function __construct( + EntityRepositoryInterface $entity_repository, + Connection $database, + InlineBlockUsageInterface $usage, + SectionStorageManagerInterface $section_storage_manager, + ?CurrentRouteMatch $current_route_match, + ) { + parent::__construct($entity_repository, $database, $usage, $section_storage_manager, $current_route_match); + } + /** * Call getTranslationFromContext() on the entity. */ - protected function getInlineBlockDependency(BlockContentInterface $block_content) { - $layout_entity_info = $this->usage->getUsage($block_content->id()); - if (empty($layout_entity_info)) { - // If the block does not have usage information then we cannot set a - // dependency. It may be used by another module besides layout builder. - return NULL; + protected function getInlineBlockDependency(BlockContentInterface $block_content, $operation): ?AccessibleInterface { + // Most patches or updates for Layout Builder on Drupal Community + // won't work if we don't call parent::getInlineBlockDependency. + $layout_entity = parent::getInlineBlockDependency($block_content, $operation); + + // Check for layout entity from parent function. + if (!$layout_entity) { + $layout_entity_info = $this->usage->getUsage($block_content->id()); + if (empty($layout_entity_info) || empty($layout_entity_info->layout_entity_type) || empty($layout_entity_info->layout_entity_id)) { + // If this is a newly added block it does not have usage information yet. + // Attempt to fetch layout_entity from section storage. + if ($block_content->isNew()) { + $section_storage = $this->current_route_match->getParameter('section_storage'); + if ($section_storage) { + $layout_entity = $section_storage->getContextValue('entity'); + } + } + + // If the block does not have usage information then we cannot set a + // dependency. It may be used by another module besides layout builder. + if (!$layout_entity) { + return NULL; + } + } + else { + // When updating or deleting an inline block, resolve the inline block + // dependency via the active revision, since it is the revision that should + // be loaded for editing purposes. + $active_operations = ['update', 'delete']; + $current_route = $this->current_route_match->getRouteObject(); + if ('view' === $operation && ($current_route && $current_route->getOption('_layout_builder'))) { + $active_operations[] = 'view'; + } + if (in_array($operation, $active_operations, TRUE)) { + $layout_entity = $this->entityRepository->getActive($layout_entity_info->layout_entity_type, $layout_entity_info->layout_entity_id); + } else { + $layout_entity = $this->entityRepository->getCanonical($layout_entity_info->layout_entity_type, $layout_entity_info->layout_entity_id); + } + } } - $layout_entity_storage = $this->entityTypeManager->getStorage($layout_entity_info->layout_entity_type); - $layout_entity = $layout_entity_storage->load($layout_entity_info->layout_entity_id); - $layout_entity = \Drupal::service('entity.repository')->getTranslationFromContext($layout_entity); + + // Else call getTranslationFromContext() on the entity. + $layout_entity = $this->entityRepository->getTranslationFromContext($layout_entity); if ($this->isLayoutCompatibleEntity($layout_entity)) { - if ($this->isBlockRevisionUsedInEntity($layout_entity, $block_content)) { + if ($this->isBlockRevisionUsedInEntity($layout_entity, $block_content) || + method_exists($this, 'isBlockUsedInEntity') && $this->isBlockUsedInEntity($layout_entity, $block_content)) { return $layout_entity; } - } + return NULL; } diff --git a/src/LayoutBuilderAtServiceProvider.php b/src/LayoutBuilderAtServiceProvider.php index 76dcaad29dece8f2ae22116eafbde2eaaf0e4394..34d59ef7f7e0171f69e67d7adaf761a265830b84 100644 --- a/src/LayoutBuilderAtServiceProvider.php +++ b/src/LayoutBuilderAtServiceProvider.php @@ -4,6 +4,7 @@ namespace Drupal\layout_builder_at; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\ServiceProviderInterface; +use Symfony\Component\DependencyInjection\Reference; /** * Layout Builder At service provider. @@ -18,6 +19,7 @@ class LayoutBuilderAtServiceProvider implements ServiceProviderInterface { if ($container->hasDefinition('layout_builder.get_block_dependency_subscriber')) { $definition = $container->getDefinition('layout_builder.get_block_dependency_subscriber'); $definition->setClass('\Drupal\layout_builder_at\EventSubscriber\SetInlineBlockDependencyWithContextTranslation'); + $definition->addArgument(new Reference('entity_type.manager')); } }