Skip to content
linkit.module 6.06 KiB
Newer Older
<?php

/**
 * @file
 * Linkit hook implementations.
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;

Emil Stjerneman's avatar
Emil Stjerneman committed
/**
 * Implements hook_ckeditor_plugin_info_alter().
 */
function linkit_ckeditor_plugin_info_alter(array &$plugins) {
  if (isset($plugins['drupallink'])) {
    $plugins['drupallink']['class'] = "Drupal\\linkit\\Plugin\\CKEditorPlugin\\LinkitDrupalLink";
  }
}

Emil Stjerneman's avatar
Emil Stjerneman committed
/**
 * Implements hook_form_FORM_ID_alter().
Emil Stjerneman's avatar
Emil Stjerneman committed
 */
function linkit_form_editor_link_dialog_alter(&$form, FormStateInterface $form_state, $form_id) {
  /** @var Drupal\filter\Entity\FilterFormat $filter_format */
Emil Stjerneman's avatar
Emil Stjerneman committed
  $filter_format = $form_state->getBuildInfo()['args'][0];

  /** @var \Drupal\Core\Entity\EntityStorageInterface $editorStorage */
  $editorStorage = Drupal::service('entity.manager')->getStorage('editor');

  /** @var \Drupal\editor\EditorInterface $editor */
  $editor = $editorStorage->load($filter_format->id());
  $plugin_settings = $editor->getSettings()['plugins']['drupallink'];

  // Do not alter the form if Linkit is not enabled for this text format.
  if (!isset($plugin_settings['linkit_enabled']) || (isset($plugin_settings['linkit_enabled']) && !$plugin_settings['linkit_enabled'])) {
    return;
  }

Emil Stjerneman's avatar
Emil Stjerneman committed
  $linkit_profile_id = $editor->getSettings()['plugins']['drupallink']['linkit_profile'];
  /** @var \Drupal\linkit\Entity\Profile $linkit_profile */
  $linkit_profile = Drupal::entityTypeManager()->getStorage('linkit_profile')->load($linkit_profile_id);

  $user_input = $form_state->getUserInput();
  $input = isset($user_input['editor_object']) ? $user_input['editor_object'] : [];
  $data_entity_type = isset($input['data-entity-type']) ? $input['data-entity-type'] : '';
  $data_entity_uuid = isset($input['data-entity-uuid']) ? $input['data-entity-uuid'] : '';

  // If the filter_html filter is activated, or any other filters using
  // XSS:filter(), it will remove 'entity:' from the href as it thinks it's a
  // bad protocol. We therefor have to restore the URI again when editing a
  // link. It is possible given that data-entity-type and data-entity-uuid is
  // set on the link element.
  try {
    if (!empty($data_entity_type) && !empty($data_entity_uuid)) {
      /** @var \Drupal\Core\Entity\EntityInterface $entity */
      $entity = \Drupal::service('entity.repository')
        ->loadEntityByUuid($data_entity_type, $data_entity_uuid);
      $href = 'entity:' . $entity->getEntityTypeId() . '/' . $entity->id();
      $access = !$entity->access('view', NULL, TRUE)->isForbidden();
    }
  }
  catch (Exception $exception) {
    // Do nothing, this is handled in the finally block.
  }
  finally {
    // If the href is not set, the data- attributes might not exists, or the
    // href is external. In that case, use the given href.
    if (!isset($href)) {
      $href = isset($input['href']) ? $input['href'] : '';
    }
  }

Emil Stjerneman's avatar
Emil Stjerneman committed
  $form['attributes']['href'] = [
    '#title' => t('Link'),
    '#type' => 'linkit',
    '#default_value' => $href,
Emil Stjerneman's avatar
Emil Stjerneman committed
    '#description' => t('Start typing to find content or paste a URL.'),
    '#autocomplete_route_name' => 'linkit.autocomplete',
    '#autocomplete_route_parameters' => [
      'linkit_profile_id' => $linkit_profile_id,
Emil Stjerneman's avatar
Emil Stjerneman committed
    ],
  ];

  $form['attributes']['link-information'] = [
    '#type' => 'inline_template',
    '#template' => '<div class="form-item linkit-link-information"><strong>{% trans %}Links to:{% endtrans %}</strong> <span>{{ link_target }}</span></div>',
    '#context' => [
      'link_target' => !empty($entity) && !empty($access) && $access ? $entity->label() : $href,
    ],
Emil Stjerneman's avatar
Emil Stjerneman committed
  ];

  // Add IMCE button if IMCE is installed and enabled for the given profile.
  if (Drupal::service('module_handler')->moduleExists('imce') && $linkit_profile->getThirdPartySetting('imce', 'use', FALSE)) {
    $form['imce-link'] = [
      '#type' => 'link',
      '#title' => t('Open IMCE file browser'),
      '#url' => Url::fromRoute('imce.page', [
        'scheme' => $linkit_profile->getThirdPartySetting('imce', 'scheme', 'public'),
      ]),
      '#options' => [
        'query' => [
          'sendto' => 'linkitImce.sendto',
      '#attributes' => [
        'class' => ['form-item', 'linkit-imce-open'],
      ],
      '#attached' => [
        'library' => [
          'linkit/linkit.imce',
        ],
      ],
  // Add #validate callback that generates data-entity-type and
  // data-entity-uuid attributes from the href attribute when appropriate.
  array_unshift($form['#validate'], 'linkit_form_editor_link_dialog_validate');
Emil Stjerneman's avatar
Emil Stjerneman committed
}

/**
 * Generates data-entity-type and data-entity-uuid attributes from href.
 */
function linkit_form_editor_link_dialog_validate(array &$form, FormStateInterface $form_state) {
Emil Stjerneman's avatar
Emil Stjerneman committed
  // Check if the 'href' attribute contains a entity: URI.
  $href = $form_state->getValue(['attributes', 'href']);
  $uri_parts = parse_url($href);

  if (!$uri_parts || !isset($uri_parts['scheme']) || $uri_parts['scheme'] !== 'entity') {
    $form_state->setValue(['attributes', 'data-entity-type'], '');
    $form_state->setValue(['attributes', 'data-entity-uuid'], '');
Emil Stjerneman's avatar
Emil Stjerneman committed
    return;
  }

  // Parse the entity: URI into an entity type ID and entity ID.
  list($entity_type_id, $entity_id) = explode('/', $uri_parts['path'], 2);

  // Check if the given entity type exists, to prevent the entity load method
  // to throw exceptions.
  $definition = \Drupal::entityTypeManager()->getDefinition($entity_type_id, FALSE);
  if (is_null($definition)) {
    $form_state->setError($form['attributes']['href'], t('Invalid URI'));
    return;
  }

Emil Stjerneman's avatar
Emil Stjerneman committed
  // Load the entity and populate the data-entity-type and data-entity-uuid
  // attributes as expected by filters.
  // @see \Drupal\editor\Plugin\Filter\EditorFileReference
  // @see \Drupal\linkit\Plugin\Filter\LinkitFilter
  $entity = \Drupal::entityTypeManager()->getStorage($entity_type_id)->load($entity_id);
  if (!empty($entity)) {
    $form_state->setValue(['attributes', 'data-entity-type'], $entity->getEntityTypeId());
    $form_state->setValue(['attributes', 'data-entity-uuid'], $entity->uuid());
    $form_state->setError($form['attributes']['href'], t('Invalid URI'));
  }

Emil Stjerneman's avatar
Emil Stjerneman committed
}