function QuickEditIntegration::entityViewAlter

Alters the entity view build for Quick Edit compatibility.

When rendering fields outside of normal view modes, Quick Edit requires that modules identify themselves with a view mode ID in the format [module_name]-[information the module needs to rerender], as prescribed by hook_quickedit_render_field().

Parameters

array $build: The built entity render array.

\Drupal\Core\Entity\EntityInterface $entity: The entity.

\Drupal\Core\Entity\Display\EntityViewDisplayInterface $display: The entity view display.

See also

hook_quickedit_render_field()

layout_builder_quickedit_render_field()

File

core/modules/layout_builder/src/QuickEditIntegration.php, line 97

Class

QuickEditIntegration
Helper methods for Quick Edit module integration.

Namespace

Drupal\layout_builder

Code

public function entityViewAlter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
    if (!$entity instanceof FieldableEntityInterface || !isset($build['_layout_builder'])) {
        return;
    }
    $build['#cache']['contexts'][] = 'user.permissions';
    if (!$this->currentUser
        ->hasPermission('access in-place editing')) {
        return;
    }
    $cacheable_metadata = CacheableMetadata::createFromRenderArray($build);
    $section_list = $this->sectionStorageManager
        ->findByContext([
        'display' => EntityContext::fromEntity($display),
        'entity' => EntityContext::fromEntity($entity),
        'view_mode' => new Context(new ContextDefinition('string'), $display->getMode()),
    ], $cacheable_metadata);
    $cacheable_metadata->applyTo($build);
    if (empty($section_list)) {
        return;
    }
    // Create a hash of the sections and use it in the unique Quick Edit view
    // mode ID. Any changes to the sections will result in a different hash,
    // forcing Quick Edit's JavaScript to recognize any changes and retrieve
    // up-to-date metadata.
    $sections_hash = hash('sha256', serialize($section_list->getSections()));
    // Track each component by their plugin ID, delta, region, and UUID.
    $plugin_ids_to_update = [];
    foreach (Element::children($build['_layout_builder']) as $delta) {
        $section = $build['_layout_builder'][$delta];
        if (!Element::isEmpty($section)) {
            
            /** @var \Drupal\Core\Layout\LayoutDefinition $layout */
            $layout = $section['#layout'];
            $regions = $layout->getRegionNames();
            foreach ($regions as $region) {
                if (isset($section[$region])) {
                    foreach ($section[$region] as $uuid => $component) {
                        if (isset($component['#plugin_id']) && $this->supportQuickEditOnComponent($component, $entity)) {
                            $plugin_ids_to_update[$component['#plugin_id']][$delta][$region][$uuid] = $uuid;
                        }
                    }
                }
            }
        }
    }
    // @todo Remove when https://www.drupal.org/node/3041850 is resolved.
    $plugin_ids_to_update = array_filter($plugin_ids_to_update, function ($info) {
        // Delta, region, and UUID each count as one.
        return count($info, COUNT_RECURSIVE) === 3;
    });
    $plugin_ids_to_update = NestedArray::mergeDeepArray($plugin_ids_to_update, TRUE);
    foreach ($plugin_ids_to_update as $delta => $regions) {
        foreach ($regions as $region => $uuids) {
            foreach ($uuids as $uuid => $component) {
                $build['_layout_builder'][$delta][$region][$uuid]['content']['#view_mode'] = static::getViewModeId($entity, $display, $delta, $uuid, $sections_hash);
            }
        }
    }
    // Alter the Quick Edit view mode ID of all fields outside of the Layout
    // Builder sections to force Quick Edit to request to the field metadata.
    // @todo Remove this logic in https://www.drupal.org/project/node/2966136.
    foreach (Element::children($build) as $field_name) {
        if ($field_name !== '_layout_builder') {
            $field_build =& $build[$field_name];
            if (isset($field_build['#view_mode'])) {
                $field_build['#view_mode'] = "layout_builder-{$display->getMode()}-non_component-{$sections_hash}";
            }
        }
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.