lb_plus-1.0.x-dev/src/Form/MediaBlockFileAssociationForm.php

src/Form/MediaBlockFileAssociationForm.php
<?php

declare(strict_types=1);

namespace Drupal\lb_plus\Form;

use Drupal\lb_plus\NewMedia;
use Drupal\user\Entity\User;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\lb_plus\LbPlusRebuildTrait;
use Drupal\lb_plus\LbPlusSettingsTrait;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\lb_plus\SectionStorageHandler;
use Drupal\Core\Block\BlockManagerInterface;
use Drupal\Core\Ajax\CloseModalDialogCommand;
use Drupal\navigation_plus\ModePluginManager;
use Drupal\lb_plus\Dropzones as DropzonesService;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\navigation_plus\NavigationPlusFormTrait;
use Drupal\Core\DependencyInjection\ClassResolverInterface;
use Drupal\layout_builder\Context\LayoutBuilderContextTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Media block file association form.
 */
final class MediaBlockFileAssociationForm extends FormBase {

  use LbPlusRebuildTrait;
  use LbPlusSettingsTrait;
  use NavigationPlusFormTrait;
  use LayoutBuilderContextTrait;

  public function __construct(
    protected SectionStorageHandler $sectionStorageHandler,
    protected EntityFieldManagerInterface $entityFieldManager,
    protected ModePluginManager $modeManager,
    protected BlockManagerInterface $blockManager,
    protected EntityTypeManagerInterface $entityTypeManager,
    protected DropzonesService $dropzones,
    protected NewMedia $newMedia,
    protected ClassResolverInterface $classResolver,
    protected UuidInterface $uuid,
  ) {}

  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('lb_plus.section_storage_handler'),
      $container->get('entity_field.manager'),
      $container->get('plugin.manager.modes'),
      $container->get('plugin.manager.block'),
      $container->get('entity_type.manager'),
      $container->get('lb_plus.dropzones'),
      $container->get('lb_plus.new_media'),
      $container->get('class_resolver'),
      $container->get('uuid'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId(): string {
    return 'lb_plus_media_block_file_association';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form_state->set('workspace_safe', TRUE);
    $file_extension = $form_state->get('file_extension');
    $file_extension = strtolower($file_extension);

    $compatible_media_types = $this->newMedia->getCompatibleMediaTypes($file_extension);
    $relevant_block_content_types = $this->getCompatibleBlockContentTypes($compatible_media_types, $form_state);

    if (empty($relevant_block_content_types)) {
      $this->messenger()->addWarning($this->t('No media types available for %file_extension files.', ['%file_extension' => ".$file_extension"]));
      $response = new AjaxResponse();
      $this->renderMessages($response);

      return $response;
    }

    $file_extension_label = ucfirst($file_extension);
    $form['description']['#markup'] = $this->t("@file_extension's can be placed in @block_types block types. Which block type would you like to place?", [
      '@file_extension' => $file_extension_label,
      '@block_types' => navigation_plus_implode(array_values($relevant_block_content_types)),
    ]);
    $form['file_extension_association'] = [
      '#type' => 'select',
      '#options' => $relevant_block_content_types,
    ];
    $form['remember'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Remember this file association'),
    ];

    $form['actions'] = [
      '#type' => 'actions',
      'submit' => [
        '#type' => 'submit',
        '#value' => $this->t('Save'),
        '#attributes' => [
          'id' => 'file-association-submit',
        ],
        '#ajax' => [
          'callback' => [$this, 'ajaxSubmit'],
          'selector' => '#file-association-submit',
        ],
      ],
    ];

    return $form;
  }

  /**
   * Ajax submission handler.
   */
  public function ajaxSubmit(array &$form, FormStateInterface $form_state) {
    $response = $form_state->get('rebuild_layout_response');
    $response->addCommand(new CloseModalDialogCommand());
    return $response;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state): void {
    $association = $form_state->getValue('file_extension_association');
    $remember = $form_state->getValue('remember');
    if ($remember) {
      $file_extension = $form_state->get('file_extension');
      $file_extension = strtolower($file_extension);
      $this->saveUserFileAssociationPreference($association, $file_extension);
      $form_state->set('update_settings_sidebar', TRUE);
    }
    $this->newMedia->createMediaBlock($association, $form_state);
  }

  /**
   * Save user file association preference.
   *
   * @param string $association
   * @param string $file_extension
   *
   * @return void
   */
  public function saveUserFileAssociationPreference(string $association, string $file_extension): void {
    $account = $this->currentUser();
    // Save the user file association preference.
    if ($account->isAuthenticated()) {
      $user = User::load($account->id());
      $settings = $user->navigation_plus_settings->getValue();
      $settings[0]['file_associations'][$file_extension] = $association;
      $user->set('navigation_plus_settings', $settings[0]);
      navigation_plus_save_outside_workspace($user);
    }
  }


  /**
   * Get block content types with media reference fields to compatible media types.
   *
   * @param array $compatible_media_types
   *   An array of MediaType entities compatible with a file extension.
   *
   * @return array
   *   An array of BlockContentType entities that have a media reference field
   *   allowing at least one of the compatible media types.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function getCompatibleBlockContentTypes(array $compatible_media_types, FormStateInterface $form_state): array {
    // What block types are allowed to be placed?
    [
      $section_storage,
      $nested_storage_path,
      $parameters,
      $current_section_storage
    ] = $this->newMedia->getSectionStorageDetails($form_state);

    $promoted_block_plugin_ids = $this->getLbPlusSetting($current_section_storage, 'promoted_blocks');
    $promoted_block_content_ids = array_map(function ($block_plugin_id) {
      return explode(':', $block_plugin_id)[1];
    }, $promoted_block_plugin_ids);

    $compatible_media_type_ids = array_map(function($media_type) {
      return $media_type->id();
    }, $compatible_media_types);

    $block_content_types = $this->entityTypeManager->getStorage('block_content_type')->loadMultiple();
    $relevant_block_content_types = [];

    foreach ($block_content_types as $block_content_type) {
      if (!in_array($block_content_type->id(), $promoted_block_content_ids)) {
        continue;
      }
      $fields = $this->entityFieldManager->getFieldDefinitions('block_content', $block_content_type->id());

      foreach ($fields as $field) {
        if ($field->getType() === 'entity_reference' && $field->getSetting('target_type') === 'media') {
          $handler_settings = $field->getSetting('handler_settings');
          $allowed_media_types = $handler_settings['target_bundles'] ?? [];

          // If no specific bundles are set (empty array), all media types are allowed.
          // Or if there's an overlap with compatible media types, include this block content type.
          if (empty($allowed_media_types) || array_intersect($allowed_media_types, $compatible_media_type_ids)) {
            $relevant_block_content_types[$block_content_type->id()] = $block_content_type->label();
            break;
          }
        }
      }
    }
    return $relevant_block_content_types;
  }

}

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

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