entity_reference_edit_link-1.1.2/entity_reference_edit_link.module

entity_reference_edit_link.module
<?php

/**
 * @file
 * This is the module to create a drop-down menu for the core toolbar.
 */

use Drupal\Core\Field\EntityReferenceFieldItemList;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Render\Element;
use Drupal\Core\Url;
use Drupal\entity_reference_edit_link\Plugin\Field\FieldWidget\EntityReferenceEditLinkAutocompleteTagsWidget;
use Drupal\entity_reference_edit_link\Plugin\Field\FieldWidget\EntityReferenceEditLinkAutocompleteWidget;
use Drupal\node\NodeForm;
use Drupal\user\Entity\User;

/**
 * Implements hook_preprocess_HOOK().
 */
function entity_reference_edit_link_preprocess_field_multiple_value_form(&$variables) {
  if (!isset($variables['element'][0]['_link'])) {
    return;
  }

  // Adds link column to the table header.
  $variables['table']['#header'][] = t('Edit Entity', [], ['context' => 'Link']);
  $element = $variables['element'];
  // Copied some part of the code from the another hook just to add the correct
  // values to the render array.
  /* @see \template_preprocess_field_multiple_value_form() */
  foreach (Element::children($element) as $key) {
    if ($key === 'add_more') {
      $variables['button'] = &$element[$key];
    }
    else {
      $items[] = &$element[$key];
    }
  }

  foreach ($items as $item) {
    $order_class = $element['#field_name'] . '-delta-order';
    $item['_weight']['#attributes']['class'] = [$order_class];
    // Remove weight and link form elements from item render array,
    // so they can be rendered in a separate table column.
    $delta_element = $item['_weight'];
    $link_element = $item['_link'] ?? NULL;
    unset($item['_weight']);
    unset($item['_link']);

    // Render actions in a separate column.
    $actions = [];
    if (isset($item['_actions'])) {
      $actions = $item['_actions'];
      unset($item['_actions']);
    }

    $cells = [
      ['data' => '', 'class' => ['field-multiple-drag']],
      ['data' => $item],
      ['data' => $actions],
      ['data' => $delta_element, 'class' => ['delta-order']],
      // Adds link element to the render array.
      ['data' => $link_element, 'class' => ['reference-link']],
    ];
    $rows[] = [
      'data' => $cells,
      'class' => ['draggable'],
    ];
  }
  $variables['table']['#rows'] = $rows;
}

/**
 * Implements hook_field_widget_info_alter().
 */
function entity_reference_edit_link_field_widget_info_alter(array &$info) {
  $info['entity_reference_autocomplete']['class'] = EntityReferenceEditLinkAutocompleteWidget::class;
  $info['entity_reference_autocomplete_tags']['class'] = EntityReferenceEditLinkAutocompleteTagsWidget::class;
}

/**
 * Implements hook_field_widget_complete_form_alter().
 *
 * @throws \Drupal\Core\Entity\EntityMalformedException
 */
function entity_reference_edit_link_field_widget_complete_form_alter(&$field_widget_complete_form, FormStateInterface $form_state, $context) {
  $widget = $context['widget'] ?? NULL;

  // Adds support of the select2 field widget.
  if (!$widget || $widget->getPluginId() != 'select2_entity_reference') {
    return;
  }
  $entity = !empty($context['items']) ? $context['items']->entity : NULL;
  $user = User::load(\Drupal::currentUser()->id());
  if (empty($entity) || !$entity->access('update', $user)) {
    return;
  }

  $field_widget_complete_form += [
    '#attached' => [
      'library' => ['entity_reference_edit_link/reference.field'],
    ],
  ];

  $field_widget_complete_form['widget'] = [
    'target_id' => $field_widget_complete_form['widget'],
    '_link' => _entity_reference_edit_link_prepare_link($widget, $context['items'], $entity),
  ];
}

/**
 * Prepares a render array for the field edit link.
 *
 * @param \Drupal\Core\Field\WidgetBase $widget
 *   Field widget object.
 * @param \Drupal\Core\Field\EntityReferenceFieldItemList $items
 *   Field items.
 * @param \Drupal\Core\Entity\EntityInterface $entity
 *   Entity for the single value field case.
 *
 * @return array
 *   Returns render array with the link.
 *
 * @throws \Drupal\Core\Entity\EntityMalformedException
 */
function _entity_reference_edit_link_prepare_link(WidgetBase $widget, EntityReferenceFieldItemList $items, mixed $entity) {
  // Check if the widget allow multiple values.
  $multiple = $widget->getPluginDefinition()['multiple_values'] ?? FALSE;
  // Prepares container for the link.
  $link = [
    '#type' => 'container',
    '#attributes' => [
      'class' => ['reference-edit-link-wrapper form-item'],
    ],
  ];
  // Build multiple links if field widget allows multiple values.
  if ($multiple) {
    // Create default link value.
    $links['default'] = [
      'title' => t('Edit'),
      'url' => Url::fromRoute('<none>'),
    ];
    // Prepares link for the field values.
    /** @var \Drupal\Core\Entity\EntityInterface $referencedEntity */
    foreach ($items->referencedEntities() as $referencedEntity) {
      if (!$referencedEntity->hasLinkTemplate('edit-form')) {
        continue;
      }
      $links[$referencedEntity->id()] = [
        'title' => $referencedEntity->label(),
        'url' => $referencedEntity->toUrl('edit-form'),
        'attributes' => [
          'target' => '_blank',
        ],
      ];
    }

    // Render multiple links as a dropbutton.
    $link['link'] = [
      '#type' => 'dropbutton',
      '#dropbutton_type' => 'small',
      '#links' => $links,
      '#attributes' => [
        'class' => ['reference-edit-link'],
        'target' => '_blank',
      ],
    ];
  }
  // Handle single value field.
  elseif ($entity->hasLinkTemplate('edit-form')) {
    $link['link'] = [
      '#type' => 'link',
      '#title' => t('Edit'),
      '#url' => $entity->toUrl('edit-form'),
      '#attributes' => [
        'class' => ['button reference-edit-link'],
        'target' => '_blank',
      ],
    ];
  }

  return $link;
}

/**
 * Implements hook_form_alter().
 */
function entity_reference_edit_link_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $formObject = $form_state->getFormObject();
  // Currently worked only for the nodes.
  if (!$formObject instanceof NodeForm || $formObject->getOperation() != 'edit') {
    return;
  }

  $node = $formObject->getEntity();
  if (!$node) {
    return;
  }
  if (_entity_reference_edit_link_allowed_content_type($node) && _entity_reference_edit_link_check_permissions()) {
    $form['#title'] = _entity_reference_edit_link_build_entity_type_link($node);
  }
}

/**
 * Implements hook_preprocess_HOOK().
 */
function entity_reference_edit_link_preprocess_page_title(&$variables) {
  // To handle Gin theme node edit page structure.
  $node = \Drupal::routeMatch()->getParameter('node');
  // Only for the node edit pages.
  if (!$node || \Drupal::routeMatch()->getRouteName() != 'entity.node.edit_form') {
    return;
  }
  if (_entity_reference_edit_link_allowed_content_type($node) && _entity_reference_edit_link_check_permissions()) {
    $variables['#title'] = _entity_reference_edit_link_build_entity_type_link($node);
  }
}

/**
 * Implements hook_theme_registry_alter().
 */
function entity_reference_edit_link_theme_registry_alter(&$theme_registry) {
  // To run module hook function before Gin theme functions.
  foreach ($theme_registry['page_title']['preprocess functions'] as $key => $value) {
    if ($value == 'entity_reference_edit_link_preprocess_page_title') {
      unset($theme_registry['page_title']['preprocess functions'][$key]);
      $theme_registry['page_title']['preprocess functions'][] = $value;
    }
  }
}

/**
 * Implements hook_entity().
 */
function _entity_reference_edit_link_build_entity_type_link($node) {
  $url = Url::fromRoute("entity.{$node->getEntityTypeId()}.field_ui_fields", [
    'node_type' => $node->bundle(),
  ],
    [
      'attributes' => ['target' => '_blank'],
    ]);
  return t('<em>Edit @type</em> @title', [
    '@type' => Link::fromTextAndUrl(node_get_type_label($node), $url)->toString(),
    '@title' => $node->label(),
  ]);
}

/**
 * Implements custom function to check allowed content types.
 */
function _entity_reference_edit_link_allowed_content_type($node) {
  return !empty($allowedContentTypes = \Drupal::config('entity_reference_edit_link.config')->get('content_types'))
    && in_array($node->bundle(), $allowedContentTypes);
}

/**
 * Checks user permissions.
 *
 * @return bool
 *   Returns TRUE if current user has specific permission.
 */
function _entity_reference_edit_link_check_permissions() {
  return \Drupal::currentUser()->hasPermission('administer node fields');
}

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

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