layout_paragraphs-1.0.x-dev/src/Controller/DuplicateController.php

src/Controller/DuplicateController.php
<?php

namespace Drupal\layout_paragraphs\Controller;

use Drupal\Core\Ajax\AfterCommand;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\AjaxHelperTrait;
use Drupal\Core\Ajax\OpenDialogCommand;
use Drupal\Core\Controller\ControllerBase;
use Drupal\layout_paragraphs\LayoutParagraphsLayout;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\layout_paragraphs\Ajax\LayoutParagraphsEventCommand;
use Drupal\layout_paragraphs\LayoutParagraphsLayoutRefreshTrait;
use Drupal\layout_paragraphs\LayoutParagraphsLayoutTempstoreRepository;
use Drupal\layout_paragraphs\Event\LayoutParagraphsDuplicateEvent;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Drupal\layout_paragraphs\Utility\Dialog;
use Drupal\layout_paragraphs\Form\ModalConfirmForm;

/**
 * Class DuplicateController.
 *
 * Duplicates a component of a Layout Paragraphs Layout.
 */
class DuplicateController extends ControllerBase {

  use LayoutParagraphsLayoutRefreshTrait;
  use AjaxHelperTrait;

  /**
   * The tempstore service.
   *
   * @var \Drupal\layout_paragraphs\LayoutParagraphsLayoutTempstoreRepository
   */
  protected $tempstore;

  /**
   * The event dispatcher service.
   *
   * @var \Symfony\Contracts\EventDispatcher\EventDispatcherInterface
   */
  protected $eventDispatcher;

  /**
   * {@inheritdoc}
   */
  public function __construct(LayoutParagraphsLayoutTempstoreRepository $tempstore, EventDispatcherInterface $event_dispatcher) {
    $this->tempstore = $tempstore;
    $this->eventDispatcher = $event_dispatcher;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('layout_paragraphs.tempstore_repository'),
      $container->get('event_dispatcher')
    );
  }

  /**
   * Duplicates a component and returns appropriate response.
   *
   * @param \Drupal\layout_paragraphs\LayoutParagraphsLayout $layout_paragraphs_layout
   *   The layout paragraphs layout object.
   * @param string $source_uuid
   *   The source component to be cloned.
   *
   * @return array|\Drupal\Core\Ajax\AjaxResponse
   *   A build array or Ajax response.
   */
  public function duplicate(LayoutParagraphsLayout $layout_paragraphs_layout, string $source_uuid) {
    $this->setLayoutParagraphsLayout($layout_paragraphs_layout);

    // Duplicate the component first.
    $duplicate_component = $this->layoutParagraphsLayout->duplicateComponent($source_uuid);

    // Dispatch the duplicate event to allow other modules to modify or cancel.
    $event = new LayoutParagraphsDuplicateEvent($this->layoutParagraphsLayout, $source_uuid, $duplicate_component);
    $this->eventDispatcher->dispatch($event, LayoutParagraphsDuplicateEvent::EVENT_NAME);

    // Check if duplication was prevented by any event subscribers.
    if ($event->isDuplicationPrevented()) {
      // Remove the duplicated component from the layout since duplication
      // was prevented.
      $this->layoutParagraphsLayout->deleteComponent($duplicate_component->getEntity()->uuid());

      if ($this->isAjax()) {
        $response = new AjaxResponse();

        // Show the prevention message using ModalConfirmForm.
        $form = $this->formBuilder()->getForm(
          ModalConfirmForm::class,
          $this->layoutParagraphsLayout,
          $event->getMessage(),
        );

        $dialog_options = Dialog::dialogSettings($this->layoutParagraphsLayout);
        $dialog_options['width'] = 'fit-content';
        $dialog_options['height'] = 'fit-content';

        $response->addCommand(new OpenDialogCommand(
          Dialog::dialogSelector($this->layoutParagraphsLayout),
          $this->t('Duplication Not Permitted'),
          $form,
          $dialog_options
        ));

        return $response;
      }
      return [
        '#type' => 'layout_paragraphs_builder',
        '#layout_paragraphs_layout' => $layout_paragraphs_layout,
      ];
    }

    // Only save to tempstore if duplication wasn't prevented.
    $this->tempstore->set($this->layoutParagraphsLayout);

    if ($this->isAjax()) {
      return $this->successfulAjaxResponse($duplicate_component, $source_uuid);
    }

    return [
      '#type' => 'layout_paragraphs_builder',
      '#layout_paragraphs_layout' => $layout_paragraphs_layout,
    ];
  }

  /**
   * Checks if duplication was blocked by event subscribers.
   *
   * @param \Drupal\layout_paragraphs\Event\LayoutParagraphsDuplicateEvent $event
   *   The duplication event.
   *
   * @return bool
   *   TRUE if duplication was blocked, FALSE otherwise.
   */
  protected function isDuplicationBlocked(LayoutParagraphsDuplicateEvent $event): bool {
    return $event->isDuplicationPrevented();
  }

  /**
   * Builds Ajax response for successful duplication.
   *
   * @param \Drupal\layout_paragraphs\LayoutParagraphsComponent $duplicate_component
   *   The duplicated component.
   * @param string $source_uuid
   *   The source component UUID.
   *
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   The Ajax response.
   */
  protected function successfulAjaxResponse($duplicate_component, string $source_uuid): AjaxResponse {
    $response = new AjaxResponse();

    if ($this->needsRefresh()) {
      return $this->refreshLayout($response);
    }

    $uuid = $duplicate_component->getEntity()->uuid();
    $rendered_item = [
      '#type' => 'layout_paragraphs_builder',
      '#layout_paragraphs_layout' => $this->layoutParagraphsLayout,
      '#uuid' => $uuid,
    ];
    $response->addCommand(new AfterCommand('[data-uuid="' . $source_uuid . '"]', $rendered_item));
    $response->addCommand(new LayoutParagraphsEventCommand($this->layoutParagraphsLayout, $uuid, 'component:insert'));

    return $response;
  }

}

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

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