Unverified Commit 87bdfdfc authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3045171 by godotislate, rlmumford, bnjmnm, ccasals, bkosborne,...

Issue #3045171 by godotislate, rlmumford, bnjmnm, ccasals, bkosborne, johndevman, shimpy, Madhura BK, phjou, xaqrox, a3hill, tim.plunkett, gnuget, grahamC, kualee: Form blocks rendered inside layout builder break save

(cherry picked from commit 0a16b0f1)
parent 59987a5f
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -190,6 +190,13 @@ function layout_builder_post_update_update_permissions() {
  }
}

/**
 * Clear caches due to addition of service decorator for entity form controller.
 */
function layout_builder_post_update_override_entity_form_controller() {
  // Empty post-update hook.
}

/**
 * Set the layout builder field as non-translatable where possible.
 */
+7 −0
Original line number Diff line number Diff line
@@ -51,3 +51,10 @@ services:
  inline_block.usage:
    class: Drupal\layout_builder\InlineBlockUsage
    arguments: ['@database']
  layout_builder.controller.entity_form:
    # Override the entity form controller to handle the entity layout_builder
    # operation.
    decorates: controller.entity_form
    class: Drupal\layout_builder\Controller\LayoutBuilderHtmlEntityFormController
    public: false
    arguments: ['@layout_builder.controller.entity_form.inner']
+59 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\layout_builder\Controller;

use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Controller\FormController;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Routing\RouteMatchInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * Overrides the entity form controller service for layout builder operations.
 */
class LayoutBuilderHtmlEntityFormController {

  use DependencySerializationTrait;

  /**
   * The entity form controller being decorated.
   *
   * @var \Drupal\Core\Controller\FormController
   */
  protected $entityFormController;

  /**
   * Constructs a LayoutBuilderHtmlEntityFormController object.
   *
   * @param \Drupal\Core\Controller\FormController $entity_form_controller
   *   The entity form controller being decorated.
   */
  public function __construct(FormController $entity_form_controller) {
    $this->entityFormController = $entity_form_controller;
  }

  /**
   * {@inheritdoc}
   */
  public function getContentResult(Request $request, RouteMatchInterface $route_match) {
    $form = $this->entityFormController->getContentResult($request, $route_match);

    // If the form render element has a #layout_builder_element_keys property,
    // first set the form element as a child of the root render array. Use the
    // keys to get the layout builder element from the form render array and
    // copy it to a separate child element of the root element to prevent any
    // forms within the layout builder element from being nested.
    if (isset($form['#layout_builder_element_keys'])) {
      $build['form'] = &$form;
      $layout_builder_element = &NestedArray::getValue($form, $form['#layout_builder_element_keys']);
      $build['layout_builder'] = $layout_builder_element;
      // Remove the layout builder element within the form.
      $layout_builder_element = [];
      return $build;
    }

    // If no #layout_builder_element_keys property, return form as is.
    return $form;
  }

}
+15 −0
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ public function buildForm(array $form, FormStateInterface $form_state, SectionSt
    $form['layout_builder'] = [
      '#type' => 'layout_builder',
      '#section_storage' => $section_storage,
      '#process' => [[static::class, 'layoutBuilderElementGetKeys']],
    ];
    $form['layout_builder_message'] = $this->buildMessage($section_storage->getContextValue('display'));

@@ -91,6 +92,20 @@ public function buildForm(array $form, FormStateInterface $form_state, SectionSt
    return parent::buildForm($form, $form_state);
  }

  /**
   * Form element #process callback.
   *
   * Save the layout builder element array parents as a property on the top form
   * element so that they can be used to access the element within the whole
   * render array later.
   *
   * @see \Drupal\layout_builder\Controller\LayoutBuilderHtmlEntityFormController
   */
  public static function layoutBuilderElementGetKeys(array $element, FormStateInterface $form_state, &$form) {
    $form['#layout_builder_element_keys'] = $element['#array_parents'];
    return $element;
  }

  /**
   * Renders a message to display at the top of the layout builder.
   *
+15 −0
Original line number Diff line number Diff line
@@ -32,6 +32,21 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
      '#type' => 'layout_builder',
      '#section_storage' => $this->getSectionStorage($form_state),
    ];
    $element['#process'][] = [static::class, 'layoutBuilderElementGetKeys'];
    return $element;
  }

  /**
   * Form element #process callback.
   *
   * Save the layout builder element array parents as a property on the top form
   * element so that they can be used to access the element within the whole
   * render array later.
   *
   * @see \Drupal\layout_builder\Controller\LayoutBuilderHtmlEntityFormController
   */
  public static function layoutBuilderElementGetKeys(array $element, FormStateInterface $form_state, &$form) {
    $form['#layout_builder_element_keys'] = $element['#array_parents'];
    return $element;
  }

Loading