mercury_editor-2.0.x-dev/src/Form/EditComponentForm.php
src/Form/EditComponentForm.php
<?php
namespace Drupal\mercury_editor\Form;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\RemoveCommand;
use Drupal\Core\Ajax\MessageCommand;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\mercury_editor\MercuryEditorTempstore;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Layout\LayoutPluginManagerInterface;
use Drupal\layout_paragraphs\LayoutParagraphsLayout;
use Drupal\mercury_editor\Ajax\IFrameAjaxResponseWrapper;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\layout_paragraphs\Ajax\LayoutParagraphsEventCommand;
use Drupal\mercury_editor\Ajax\MercuryEditorUpdateStateCommand;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Drupal\layout_paragraphs\LayoutParagraphsLayoutTempstoreRepository;
use Drupal\layout_paragraphs\Form\EditComponentForm as LayoutParagraphsEditComponentForm;
/**
* Class for editing a component in Mercury Editor.
*/
class EditComponentForm extends LayoutParagraphsEditComponentForm {
/**
* {@inheritDoc}
*/
public function __construct(
LayoutParagraphsLayoutTempstoreRepository $tempstore,
EntityTypeManagerInterface $entity_type_manager,
LayoutPluginManagerInterface $layout_plugin_manager,
ModuleHandlerInterface $module_handler,
EventDispatcherInterface $event_dispatcher,
EntityRepositoryInterface $entity_repository,
protected IFrameAjaxResponseWrapper $iFrameAjaxResponseWrapper,
protected MercuryEditorTempstore $mercuryEditorTempstore,
) {
parent::__construct($tempstore, $entity_type_manager, $layout_plugin_manager, $module_handler, $event_dispatcher, $entity_repository);
}
/**
* {@inheritDoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('layout_paragraphs.tempstore_repository'),
$container->get('entity_type.manager'),
$container->get('plugin.manager.core.layout'),
$container->get('module_handler'),
$container->get('event_dispatcher'),
$container->get('entity.repository'),
$container->get('mercury_editor.iframe_ajax_response_wrapper'),
$container->get('mercury_editor.tempstore_repository'),
$container->get('mercury_editor.context'),
);
}
/**
* {@inheritDoc}
*/
public function buildForm(
array $form,
FormStateInterface $form_state,
?LayoutParagraphsLayout $layout_paragraphs_layout = NULL,
?string $component_uuid = NULL,
) {
$form = parent::buildForm($form, $form_state, $layout_paragraphs_layout, $component_uuid);
$form['messages'] = [
'#type' => 'container',
'#attributes' => ['class' => ['me-form-messages']],
'#weight' => -10,
];
$form['actions']['submit']['#attributes']['class'][] = 'me-autosave-btn';
$form['#attributes']['class'][] = 'me-autosave-form';
return $form;
}
/**
* {@inheritDoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// If the layout has changed and regions have been removed, move orphaned
// items to the first available region.
if ($selected_layout = $form_state->getValue(['layout_paragraphs', 'layout'])) {
$section = $this->layoutParagraphsLayout->getLayoutSection($this->paragraph);
if ($section && $selected_layout != $section->getLayoutId()) {
$old_regions = $this->getLayoutRegionNames($section->getLayoutId());
$new_regions = $this->getLayoutRegionNames($selected_layout);
$default_region = array_key_first($new_regions);
$section = $this->layoutParagraphsLayout->getLayoutSection($this->paragraph);
foreach ($old_regions as $region_name => $region) {
if ($section->getComponentsForRegion($region_name) && empty($new_regions[$region_name])) {
$form_state->setValue([
'layout_paragraphs',
'move_items',
$region_name,
], $default_region);
}
}
}
}
parent::submitForm($form, $form_state);
$mercury_editor_entity = $this->mercuryEditorTempstore
->get($this->layoutParagraphsLayout->getEntity()->uuid());
$this->mercuryEditorTempstore->saveState($mercury_editor_entity);
$form_state->setRebuild();
}
/**
* {@inheritDoc}
*
* Don't replace the form if there are errors.
*/
public function ajaxSubmit(array &$form, FormStateInterface $form_state) {
$response = new AjaxResponse();
if (!$form_state->hasAnyErrors()) {
$response = $this->successfulAjaxSubmit($form, $form_state);
}
$this->ajaxAddMessages($form, $form_state, $response);
return $response;
}
/**
* {@inheritDoc}
*/
public function successfulAjaxSubmit(array $form, FormStateInterface $form_state) {
$response = new AjaxResponse();
if ($this->needsRefresh()) {
$layout = $this->renderLayout();
$dom_selector = '[data-lpb-id="' . $this->layoutParagraphsLayout->id() . '"]';
$this->iFrameAjaxResponseWrapper->addCommand(new ReplaceCommand($dom_selector, $layout));
$response->addCommand($this->iFrameAjaxResponseWrapper->getWrapperCommand());
return $response;
}
$uuid = $this->paragraph->uuid();
$rendered_item = $this->renderParagraph($uuid);
$this->iFrameAjaxResponseWrapper->addCommand(new ReplaceCommand("[data-uuid={$uuid}]", $rendered_item));
$this->iFrameAjaxResponseWrapper->addCommand(new LayoutParagraphsEventCommand($this->layoutParagraphsLayout, $uuid, 'component:update', ['editing' => TRUE]));
$response->addCommand($this->iFrameAjaxResponseWrapper->getWrapperCommand());
$response->addCommand(new MercuryEditorUpdateStateCommand(
$this->mercuryEditorTempstore,
$this->layoutParagraphsLayout->getEntity(),
));
return $response;
}
/**
* Adds messages to an ajax response.
*
* @param array $form
* The form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
* @param \Drupal\Core\Ajax\AjaxResponse $response
* The ajax response.
*/
protected function ajaxAddMessages(array $form, FormStateInterface $form_state, AjaxResponse $response) {
$response->addCommand(new RemoveCommand('.layout-paragraphs-component-form .me-form-messages .messages'));
foreach ($this->messenger()->all() as $type => $messages) {
foreach ($messages as $message) {
$response->addCommand(new MessageCommand($message, '.layout-paragraphs-component-form .me-form-messages', ['type' => $type], FALSE));
}
}
$this->messenger()->deleteAll();
}
/**
* {@inheritdoc}
*/
public function orphanedItemsElement(array &$form, $form_state) {
// In Mercury Editor, we do not provide an interface for moving orphaned
// items, so we do not need to implement this method.
}
}
