layout_builder_paragraphs-1.0.x-dev/src/Form/AddParagraphForm.php

src/Form/AddParagraphForm.php
<?php

namespace Drupal\layout_builder_paragraphs\Form;

use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\SubformState;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\Core\Form\SubformStateInterface;
use Drupal\layout_builder\LayoutBuilderHighlightTrait;
use Drupal\layout_builder\SectionComponent;
use Drupal\layout_builder\SectionStorageInterface;
use Drupal\layout_builder\Form\ConfigureBlockFormBase;
use Drupal\layout_builder_paragraphs\Controller\ModalLayoutRebuildTrait;

/**
 * Class AddParagraphForm.
 */
class AddParagraphForm extends ConfigureBlockFormBase {

  use LayoutBuilderHighlightTrait;
  use ModalLayoutRebuildTrait;  // Override LayoutRebuildTrait.

  /**
   * Drupal\Core\Entity\EntityTypeManagerInterface definition.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    $instance = parent::create($container);
    $instance->entityTypeManager = $container->get('entity_type.manager');
    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'layout_builder_paragraphs_add_paragraph_form';
  }

  /**
   * {@inheritdoc}
   */
  protected function submitLabel() {
    return $this->t('Add paragraph and return to layout builder');
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, SectionStorageInterface $section_storage = NULL, $delta = NULL, $region = NULL, $plugin_id = NULL, $paragraph_type = NULL) {

    // Alter plugin id to match that of paragraph_blocks format, e.g.
    // paragraph_field:node:field_contents:0:landing_page
    $plugin_id = 'paragraph_field:' . $plugin_id;
    $form_state->set('plugin_id', $plugin_id);

    // The following is copied from AddBlockForm.
    // Only generate a new component once per form submission.
    if (!$component = $form_state->get('layout_builder__component')) {
      $component = new SectionComponent($this->uuidGenerator->generate(), $region, ['id' => $plugin_id]);
      $section_storage->getSection($delta)->appendComponent($component);
      $form_state->set('layout_builder__component', $component);
    }
    $form['#attributes']['data-layout-builder-target-highlight-id'] = $this->blockAddHighlightId($delta, $region);

    // The following is copied from ConfigureBlockFormBase.
    $this->sectionStorage = $section_storage;
    $this->delta = $delta;
    $this->uuid = $component->getUuid();
    $this->block = $component->getPlugin();

    $form_state->setTemporaryValue('gathered_contexts', $this->getPopulatedContexts($section_storage));
    $contexts = $this->getPopulatedContexts($section_storage);

    // @todo Remove once https://www.drupal.org/node/2268787 is resolved.
    $form_state->set('block_theme', $this->config('system.theme')->get('default'));

    $form['#tree'] = TRUE;
    $form['settings'] = [];
    $subform_state = SubformState::createForSubform($form['settings'], $form, $form_state);
    $form['settings'] = $this->getPluginForm($this->block)->buildConfigurationForm($form['settings'], $subform_state);

    // Hide the settings fields when suppressed in paragraph_blocks.
    // @see \Drupal\paragraph_blocks\Plugin\Block\ParagraphBlock::buildConfigurationForm()
    if ($this->config('paragraph_blocks.settings')->get('suppress_label')) {
      if (isset($form['settings']['admin_label'])) unset($form['settings']['admin_label']);
    }

    // Paragraph form creation. Partially copied from:
    // https://www.webomelette.com/how-render-entity-field-widgets-inside-custom-form-drupal-8
    // Set the entity and bundle.
    $entity = $this->entityTypeManager->getStorage('paragraph')->create([
      'type' => $paragraph_type,
    ]);
    // Initiate the form state.
    $form_state->set('entity', $entity);
    // Retrieve and assign the parent entity.
    $parent_entity = $section_storage->getContextValue('entity');
    $field_name = PARAGRAPH_FIELD;
    $entity->setParentEntity($parent_entity, $field_name);
    // Set langcode to parent langcode.
    $parent_langcode = $parent_entity->language()->getId();
    $entity->set('langcode', $parent_langcode);
    // Build and assign the form display.
    $form_display = EntityFormDisplay::collectRenderDisplay($entity, 'default');
    $form_display->buildForm($entity, $form, $form_state);
    $form_state->set('form_display', $form_display);
    // Assign form parents.
    // @TODO: find out if this is necessary?
    $form['#parents'] = [];

    // The following is copied from ConfigureBlockFormBase.
    // Add submit button.
    $form['actions'] = [
      '#type' => 'actions',
      'submit' => [
        '#type' => 'submit',
        '#value' => $this->submitLabel(),
        '#button_type' => 'primary',
      ],
      '#weight' => 100,
    ];

    if ($this->isAjax()) {
      // @todo Fix ajax fields (e.g. media) breaking form submit in full-page form.
      //   This occurs when ajaxified elements cause form to be rebuilt in ajax
      //   mode, which in turn causes form to assume it is rendering in a modal.
      //   When the form is reloaded without rebuilding (e.g. when there is a 
      //   validation error), unnecessary ajax handlers remain on the submit button.
      // $form['actions']['submit']['#ajax']['callback'] = '::ajaxSubmit';
      // @todo static::ajaxSubmit() requires data-drupal-selector to be the same
      //   between the various Ajax requests. A bug in
      //   \Drupal\Core\Form\FormBuilder prevents that from happening unless
      //   $form['#id'] is also the same. Normally, #id is set to a unique HTML
      //   ID via Html::getUniqueId(), but here we bypass that in order to work
      //   around the data-drupal-selector bug. This is okay so long as we
      //   assume that this form only ever occurs once on a page. Remove this
      //   workaround in https://www.drupal.org/node/2897377.
      $form['#id'] = Html::getId($form_state->getBuildInfo()['form_id']);
    }

    // Mark this as an administrative page for JavaScript ("Back to site" link).
    $form['#attached']['drupalSettings']['path']['currentPathIsAdmin'] = TRUE;

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    foreach ($form_state->getValues() as $key => $value) {
      // @TODO: Validate fields.
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // Retrieve the form display and entity.
    $form_display = $form_state->get('form_display');
    $entity = $form_state->get('entity');
    $plugin_id = $form_state->get('plugin_id');
    // Make sure that we have the complete form state.
    // @see: docroot/core/modules/layout_builder/src/Plugin/Block/InlineBlock.php:184
    $complete_form_state = $form_state instanceof SubformStateInterface ? $form_state->getCompleteFormState() : $form_state;
    // Extract the form values and populate it to the entity.
    $form_display->extractFormValues($entity, $form, $complete_form_state);
    $entity->save();

    // Add the reference to the newly created paragraph in the parent entity.
    // @TODO: don't hardcode the field as field_contents.
    $parent_entity = $entity->getParentEntity();
    $original_para_count = $parent_entity->{PARAGRAPH_FIELD}->count();
    $parent_entity->{PARAGRAPH_FIELD}->appendItem([
      'target_id' => $entity->id(),
      'target_revision_id' => $entity->getRevisionId(),
      'langcode' => $entity->get('langcode'),
    ]);
    $parent_entity->save();

    // Update the entity object stored in the section storage with new paragraph.
    $context_entity = $this->sectionStorage->getContextValue('entity');
    $context_entity->{PARAGRAPH_FIELD}->setValue($parent_entity->{PARAGRAPH_FIELD}->getValue());
    $this->sectionStorage->setContextValue('entity', $context_entity);

    // Hardcoded configuration for paragraph_blocks.

    $configuration = [
      'id' => $plugin_id,
      'label' => 'Paragraph item ' . $original_para_count,
      'provider' => 'paragraph_blocks',
      'label_display' => '',
      'context_mapping' => [
        'entity' => 'layout_builder.entity',
      ],
    ];

    // The following is copied from ConfigureBlockFormBase.
    $section = $this->sectionStorage->getSection($this->delta);
    $section->getComponent($this->uuid)->setConfiguration($configuration);

    $this->layoutTempstoreRepository->set($this->sectionStorage);
    $form_state->setRedirectUrl($this->sectionStorage->getLayoutBuilderUrl());
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc