ckeditor_mentions-8.x-2.x-dev/src/Plugin/CKEditor5Plugin/Mentions.php

src/Plugin/CKEditor5Plugin/Mentions.php
<?php

namespace Drupal\ckeditor_mentions\Plugin\CKEditor5Plugin;

use Drupal\ckeditor5\Plugin\CKEditor5PluginConfigurableInterface;
use Drupal\ckeditor5\Plugin\CKEditor5PluginConfigurableTrait;
use Drupal\ckeditor5\Plugin\CKEditor5PluginDefault;
use Drupal\ckeditor_mentions\MentionsType\MentionsTypeBase;
use Drupal\ckeditor_mentions\MentionsType\MentionsTypeManager;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Url;
use Drupal\editor\EditorInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Defines the "mentions" plugin.
 *
 * @CKEditor5Plugin(
 *   id = "ckeditor_mentions_mentions",
 *   ckeditor5 = @CKEditor5AspectsOfCKEditor5Plugin(
 *   plugins = {
 *     "mention.Mention",
 *     "drupalMention.DrupalMention"
 *   }
 *   ),
 *   drupal = @DrupalAspectsOfCKEditor5Plugin(
 *     label = @Translation("Mentions"),
 *     library = "ckeditor_mentions/ckeditor.plugin.mention.drupal",
 *     elements = {
 *       "<a>",
 *        "<a class data-mention data-mention-uuid data-entity-id data-entity-uuid data-plugin href>"
 *     }
 *   )
 * )
 */
class Mentions extends CKEditor5PluginDefault implements CKEditor5PluginConfigurableInterface, ContainerFactoryPluginInterface {
  use CKEditor5PluginConfigurableTrait;

  /**
   * Mentions Plugin Manager.
   */
  protected MentionsTypeManager $mentionsPluginManager;

  /**
   * Entity Type Bundle Info.
   */
  protected EntityTypeBundleInfoInterface $entityTypeBundleInfo;

  /**
   * {@inheritDoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    $instance = new static($configuration, $plugin_id, $plugin_definition);
    $instance->mentionsPluginManager = $container->get('plugin.manager.mentions_type');
    $instance->entityTypeBundleInfo = $container->get('entity_type.bundle.info');
    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
    $settings = $this->configuration;

    foreach ($this->mentionsPluginManager->getAllMentionsTypes() as $mentionsType => $mentionsLabel) {
      $form['plugins'][$mentionsType]['#type'] = 'fieldset';
      $form['plugins'][$mentionsType]['enable'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Enable Mentions: %type', ['%type' => $mentionsLabel]),
        '#default_value' => !empty($settings['plugins'][$mentionsType]['enable']) ? $settings['plugins'][$mentionsType]['enable'] : FALSE,
        '#attributes' => ['data-use-mentions--' . $mentionsType => TRUE],
      ];

      $form['plugins'][$mentionsType]['marker'] = [
        '#type' => 'textfield',
        '#maxlength' => '1',
        '#title' => $this->t('Marker'),
        '#description' => $this->t('The character that should trigger autocompletion.'),
        '#default_value' => !empty($settings['plugins'][$mentionsType]['marker']) ? $settings['plugins'][$mentionsType]['marker'] : '@',
        '#states' => [
          'visible' => [
            ':input[data-use-mentions--' . $mentionsType . ']' => ['checked' => TRUE],
          ],
          'required' => [
            ':input[data-use-mentions--' . $mentionsType . ']' => ['checked' => TRUE],
          ],
        ],
      ];

      $form['plugins'][$mentionsType]['removeMarker'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Remove Marker'),
        '#description' => $this->t('By default, the marker that triggers the autocomplete is displayed before the mentioned entity text. This option will remove the marker from the displayed text.'),
        '#default_value' => !empty($settings['plugins'][$mentionsType]['removeMarker']) ? $settings['plugins'][$mentionsType]['removeMarker'] : FALSE,
        '#states' => [
          'visible' => [
            ':input[data-use-mentions--' . $mentionsType . ']' => ['checked' => TRUE],
          ],
        ],
      ];

      $form['plugins'][$mentionsType]['charcount'] = [
        '#type' => 'number',
        '#min' => 0,
        '#title' => $this->t('Character Count'),
        '#description' => $this->t('Enter minimum number of characters that must be typed to trigger mention match.'),
        '#default_value' => $settings['plugins'][$mentionsType]['charcount'] ?? 2,
        '#states' => [
          'visible' => [
            ':input[data-use-mentions--' . $mentionsType . ']' => ['checked' => TRUE],
          ],
        ],
      ];

      $form['plugins'][$mentionsType]['dropdownLimit'] = [
        '#type' => 'number',
        '#min' => 1,
        '#title' => $this->t('Dropdown limit'),
        '#description' => $this->t('Specify how many available elements the users be able to see in the dropdown list.'),
        '#default_value' => $settings['plugins'][$mentionsType]['dropdownLimit'] ?? MentionsTypeBase::DEFAULT_DROPDOWN_LIMIT,
        '#states' => [
          'visible' => [
            ':input[data-use-mentions--' . $mentionsType . ']' => ['checked' => TRUE],
          ],
        ],
      ];

      // Check if the mentions type corresponds to a bundable entity type.
      $mentionsTypePlugin = $this->mentionsPluginManager->createInstance($mentionsType);
      if ($mentionsTypePlugin->isBundable()) {
        // Get available bundles for this entity type.
        $entityType = $mentionsTypePlugin->getPluginDefinition()['entity_type'];
        $bundles = $this->entityTypeBundleInfo->getBundleInfo($entityType);
        $bundleOptions = [];
        foreach ($bundles as $bundle_id => $bundle_info) {
          $bundleOptions[$bundle_id] = $bundle_info['label'];
        }

        $form['plugins'][$mentionsType]['filterByBundle'] = [
          '#type' => 'checkboxes',
          '#title' => $this->t('Filter by Bundle'),
          '#description' => $this->t('Select which bundles should be available for mentions. Leave empty to allow all bundles.'),
          '#options' => $bundleOptions,
          '#multiple' => TRUE,
          '#default_value' => !empty($settings['plugins'][$mentionsType]['filterByBundle']) ? $settings['plugins'][$mentionsType]['filterByBundle'] : [],
          '#states' => [
            'visible' => [
              ':input[data-use-mentions--' . $mentionsType . ']' => ['checked' => TRUE],
            ],
          ],
        ];
      }
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      'plugins' => [],
    ];
  }

  /**
   * {@inheritDoc}
   */
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
    $markers = [];
    $mentionTypeFormValues = $form_state->getValue(['plugins']);

    // Collect markers from enabled mention types.
    foreach ($mentionTypeFormValues as $mentionsType => $mentionsTypeConfiguration) {
      // Only validate enabled mention types:
      if (empty($mentionsTypeConfiguration['enable'])) {
        continue;
      }

      $marker = $mentionsTypeConfiguration['marker'];
      if (isset($markers[$marker])) {
        // Duplicate marker found, set validation error.
        $form_state->setErrorByName(
          "plugins][$mentionsType][marker",
          $this->t('The marker "@marker" is already used by "@existing_type". Each mention type must have a unique marker.', [
            '@marker' => $marker,
            '@existing_type' => $markers[$marker],
          ])
        );
      }
      else {
        $markers[$marker] = $mentionsType;
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
    $configuration = [];

    foreach ($this->mentionsPluginManager->getAllMentionsTypes() as $mentionsType => $mentionsLabel) {
      $mentionsTypeConfiguration = $form_state->getValue([
        'plugins',
        $mentionsType,
      ]);
      if ($mentionsTypeConfiguration['enable']) {
        $mentionsTypeConfiguration['id'] = $mentionsType;
        $mentionsTypeConfiguration['enable'] = (bool) $mentionsTypeConfiguration['enable'];
        $mentionsTypeConfiguration['removeMarker'] = (bool) $mentionsTypeConfiguration['removeMarker'];
        $mentionsTypeConfiguration['charcount'] = (int) $mentionsTypeConfiguration['charcount'];
        $mentionsTypeConfiguration['dropdownLimit'] = (int) $mentionsTypeConfiguration['dropdownLimit'];

        // Handle filterByBundle for bundable entity types.
        $mentionsTypePlugin = $this->mentionsPluginManager->createInstance($mentionsType);
        if ($mentionsTypePlugin->isBundable()) {
          // We need to filter out the 0 value because it's not a valid bundle:
          $filteredBundles = array_values(array_filter($mentionsTypeConfiguration['filterByBundle'], function ($bundle) {
            return $bundle != '0' ? $bundle : NULL;
          }));
          $mentionsTypeConfiguration['filterByBundle'] = $filteredBundles;
        }

        $configuration[$mentionsType] = $mentionsTypeConfiguration;
      }
    }

    $this->configuration['plugins'] = $configuration;
  }

  /**
   * {@inheritDoc}
   */
  public function getDynamicPluginConfig(array $static_plugin_config, EditorInterface $editor): array {
    $options = [];

    foreach ($this->configuration['plugins'] as $settings) {
      $urlParams = [
        'editor_id' => $editor->id(),
        'plugin_id' => $settings['id'],
        'match' => '--match--',
      ];

      $options['feeds'][] = [
        'marker' => $settings['marker'],
        'feed' => [
          'func' => [
            'name' => 'CKEditor5.drupalMention.MentionsAjax.initialize',
            'args' => [
              [
                'type' => $settings['id'],
                'url' => Url::fromRoute('ckeditor_mentions.ajax_callback', $urlParams)->setAbsolute()->toString(),
                'marker' => $settings['marker'],
                'removeMarker' => $settings['removeMarker'],
              ],
            ],
            'invoke' => TRUE,
          ],
        ],
        'itemRenderer' => [
          'func' => [
            'name' => 'CKEditor5.drupalMention.MentionsAjax.itemRender',
          ],
        ],
        'minimumCharacters' => $settings['charcount'],
        'drupalMentionsType' => $settings['id'],
        'dropdownLimit' => $settings['dropdownLimit'],
      ];
    }

    if (!$options) {
      return [];
    }

    return ['mention' => $options];
  }

}

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

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