* Provides hook implementations for Layout Builder.
*/
+use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay;
use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplayStorage;
use Drupal\layout_builder\Form\LayoutBuilderEntityViewDisplayForm;
+use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
+use Drupal\layout_builder\Entity\LayoutEntityDisplayInterface;
+use Drupal\layout_builder\Plugin\Block\ExtraFieldBlock;
+use Drupal\layout_builder\InlineBlockEntityOperations;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Access\AccessResult;
/**
* Implements hook_help().
$sample_entity_generator->delete($field_config->getTargetEntityTypeId(), $field_config->getTargetBundle());
\Drupal::service('plugin.manager.block')->clearCachedDefinitions();
}
+
+/**
+ * Implements hook_entity_view_alter().
+ *
+ * ExtraFieldBlock block plugins add placeholders for each extra field which is
+ * configured to be displayed. Those placeholders are replaced by this hook.
+ * Modules that implement hook_entity_extra_field_info() use their
+ * implementations of hook_entity_view_alter() to add the rendered output of
+ * the extra fields they provide, so we cannot get the rendered output of extra
+ * fields before this point in the view process.
+ * layout_builder_module_implements_alter() moves this implementation of
+ * hook_entity_view_alter() to the end of the list.
+ *
+ * @see \Drupal\layout_builder\Plugin\Block\ExtraFieldBlock::build()
+ * @see layout_builder_module_implements_alter()
+ */
+function layout_builder_entity_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
+ if ($display instanceof LayoutEntityDisplayInterface) {
+ /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $field_manager */
+ $field_manager = \Drupal::service('entity_field.manager');
+ $extra_fields = $field_manager->getExtraFields($entity->getEntityTypeId(), $entity->bundle());
+ if (!empty($extra_fields['display'])) {
+ foreach ($extra_fields['display'] as $field_name => $extra_field) {
+ // If the extra field is not set replace with an empty array to avoid
+ // the placeholder text from being rendered.
+ $replacement = isset($build[$field_name]) ? $build[$field_name] : [];
+ ExtraFieldBlock::replaceFieldPlaceholder($build, $replacement, $field_name);
+ // After the rendered field in $build has been copied over to the
+ // ExtraFieldBlock block we must remove it from its original location or
+ // else it will be rendered twice.
+ unset($build[$field_name]);
+ }
+ }
+ }
+}
+
+/**
+ * Implements hook_builder_module_implements_alter().
+ */
+function layout_builder_module_implements_alter(&$implementations, $hook) {
+ if ($hook === 'entity_view_alter') {
+ // Ensure that this module's implementation of hook_entity_view_alter() runs
+ // last so that other modules that use this hook to render extra fields will
+ // run before it.
+ $group = $implementations['layout_builder'];
+ unset($implementations['layout_builder']);
+ $implementations['layout_builder'] = $group;
+ }
+}
+
+/**
+ * Implements hook_entity_presave().
+ */
+function layout_builder_entity_presave(EntityInterface $entity) {
+ if (\Drupal::moduleHandler()->moduleExists('block_content')) {
+ /** @var \Drupal\layout_builder\InlineBlockEntityOperations $entity_operations */
+ $entity_operations = \Drupal::classResolver(InlineBlockEntityOperations::class);
+ $entity_operations->handlePreSave($entity);
+ }
+}
+
+/**
+ * Implements hook_entity_delete().
+ */
+function layout_builder_entity_delete(EntityInterface $entity) {
+ if (\Drupal::moduleHandler()->moduleExists('block_content')) {
+ /** @var \Drupal\layout_builder\InlineBlockEntityOperations $entity_operations */
+ $entity_operations = \Drupal::classResolver(InlineBlockEntityOperations::class);
+ $entity_operations->handleEntityDelete($entity);
+ }
+}
+
+/**
+ * Implements hook_cron().
+ */
+function layout_builder_cron() {
+ if (\Drupal::moduleHandler()->moduleExists('block_content')) {
+ /** @var \Drupal\layout_builder\InlineBlockEntityOperations $entity_operations */
+ $entity_operations = \Drupal::classResolver(InlineBlockEntityOperations::class);
+ $entity_operations->removeUnused();
+ }
+}
+
+/**
+ * Implements hook_plugin_filter_TYPE_alter().
+ */
+function layout_builder_plugin_filter_block_alter(array &$definitions, array $extra, $consumer) {
+ // @todo Determine the 'inline_block' blocks should be allowed outside
+ // of layout_builder https://www.drupal.org/node/2979142.
+ if ($consumer !== 'layout_builder') {
+ foreach ($definitions as $id => $definition) {
+ if ($definition['id'] === 'inline_block') {
+ unset($definitions[$id]);
+ }
+ }
+ }
+}
+
+/**
+ * Implements hook_ENTITY_TYPE_access().
+ */
+function layout_builder_block_content_access(EntityInterface $entity, $operation, AccountInterface $account) {
+ /** @var \Drupal\block_content\BlockContentInterface $entity */
+ if ($operation === 'view' || $entity->isReusable() || empty(\Drupal::service('inline_block.usage')->getUsage($entity->id()))) {
+ // If the operation is 'view' or this is reusable block or if this is
+ // non-reusable that isn't used by this module then don't alter the access.
+ return AccessResult::neutral();
+ }
+
+ if ($account->hasPermission('configure any layout')) {
+ return AccessResult::allowed();
+ }
+ return AccessResult::forbidden();
+}