datafield-1.x-dev/src/Plugin/Field/FieldWidget/DataFieldTable.php

src/Plugin/Field/FieldWidget/DataFieldTable.php
<?php

namespace Drupal\datafield\Plugin\Field\FieldWidget;

use Drupal\Component\Utility\Crypt;
use Drupal\Core\Field\Attribute\FieldWidget;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Site\Settings;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\views\Views;

/**
 * Plugin implementation of the 'data_field' widget.
 */
#[FieldWidget(
  id: 'data_field_table_widget',
  label: new TranslatableMarkup('Data Field Table'),
  field_types: ['data_field'],
)]
class DataFieldTable extends DataField {

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings(): array {
    $settings = [
      'field_reference' => '',
    ];
    return $settings + parent::defaultSettings();
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state): array {
    $elements = parent::settingsForm($form, $form_state);
    $field_settings = $this->fieldDefinition->getSetting('field_settings');
    $storage_settings = $this->fieldDefinition->getFieldStorageDefinition()->getSetting('columns');
    $options = [];
    foreach ($storage_settings as $subfield => $columns) {
      if ($columns['type'] == 'entity_reference') {
        $options[$subfield] = $field_settings[$subfield]['label'];
      }
    }
    $field_reference = $this->getSetting('field_reference');
    if (!empty($options)) {
      $elements['field_reference'] = [
        '#type' => 'select',
        '#options' => $options,
        '#empty_option' => $this->t('- Select -'),
        '#title' => $this->t('Reference field'),
        '#description' => $this->t('Add a multiple search button on reference, only works with first column entity reference'),
        '#default_value' => $field_reference,
      ];
    }
    // Make the search entity reference the first column.
    if (!empty($field_reference)) {
      $elements["widget_settings"][$field_reference]["weight"]["#default_value"] = -1;
    }
    return $elements;
  }

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state): array {
    $storage = $this->getFormElement($items, $delta, $element, $form, $form_state);
    if (empty($storage)) {
      return [];
    }
    $cardinality = $this->fieldDefinition->getFieldStorageDefinition()->getCardinality();
    $widget = [
      '#type' => 'table',
      '#base_type' => 'data_field',
    ];
    if ($cardinality != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
      $widget += [
        '#header' => $this->buildTableHeader(),
        '#title' => $element["#title"],
        '#caption' => $element["#title"],
        '#attributes' => [
          'class' => ['caption-top'],
        ],
      ];
    }
    return $element + $widget + $storage;
  }

  /**
   * {@inheritDoc}
   */
  private function buildTableHeader() {
    $header = [];
    $subfields = $this->getFieldSetting('columns');
    $widgetSettings = $this->getSetting('widget_settings');
    if (!empty($widgetSettings)) {
      uasort($widgetSettings, [
        'Drupal\Component\Utility\SortArray',
        'sortByWeightElement',
      ]);
      $subfields = $widgetSettings;
    }
    $fieldSettings = $this->getFieldSetting('field_settings');
    foreach (array_keys($subfields) as $subfield) {
      $item = $this->getFieldSetting('columns')[$subfield];
      if (!empty($widgetSettings[$subfield]) && empty($widgetSettings[$subfield]['field_display'])) {
        continue;
      }
      if (!empty($widgetSettings[$subfield]) && $widgetSettings[$subfield]['label_display'] == 'hidden') {
        $header[] = '';
        continue;
      }
      $header[] = $fieldSettings[$subfield]['label'] ?? $item['name'];
    }
    $settings = $this->getSettings();
    if (!empty($settings['operation'])) {
      $header[] = '';
    }
    return $header;
  }

  /**
   * {@inheritDoc}
   */
  public function formMultipleElements(FieldItemListInterface $items, array &$form, FormStateInterface $form_state) {
    $field_name = $this->fieldDefinition->getName();
    $field_state = static::getWidgetState($form['#parents'], $field_name, $form_state);
    $items_total = count($items);
    $cardinality = $this->fieldDefinition->getFieldStorageDefinition()->getCardinality();
    $removed = 'datafield_removed_empty' . $field_name;
    if ($items_total && $cardinality == -1 && !$form_state->get($removed)) {
      if (empty($field_state['array_parents'])) {
        $field_state['items_count'] -= 1;
        static::setWidgetState($form['#parents'], $field_name, $form_state, $field_state);
      }
      $form_state->set($removed, TRUE);
    }
    $elements = parent::formMultipleElements($items, $form, $form_state);
    if (!empty($field_reference = $this->getSetting('field_reference'))) {
      $fieldDefinition = $this->fieldDefinition->getSetting('field_settings');
      $elements['#field_reference'] = $field_reference;
      $elements['#field_reference_title'] = str_replace('"', '', $fieldDefinition[$field_reference]['label']);
      $fieldSettings = $this->getFieldSetting('field_settings')[$field_reference];
      $elements['#entity_reference_type'] = $fieldSettings['entity_reference_type'];
      $elements['#target_bundles'] = $fieldSettings['target_bundles'];
      $selection_settings = [
        'match_operator' => 'CONTAINS',
        'match_limit' => 10,
      ];
      $checkView = explode(':', $elements['#target_bundles']);
      if (empty($checkView[1])) {
        $fieldSettings["handler"] = 'default:' . $fieldSettings['entity_reference_type'];
        $selection_settings['target_bundles'] = [$elements['#target_bundles'] => $elements['#target_bundles']];
      }
      else {
        $fieldSettings["handler"] = 'views';
        $selection_settings['view'] = [
          'view_name' => $checkView[0],
          'display_name' => $checkView[1],
          'arguments' => [],
        ];
      }
      $data = serialize($selection_settings) . $fieldSettings['entity_reference_type'] . $fieldSettings["handler"];
      $selection_settings_key = Crypt::hmacBase64($data, Settings::getHashSalt());
      $key_value_storage = $this->keyValue->get('entity_autocomplete');
      if (!$key_value_storage->has($selection_settings_key)) {
        $key_value_storage->set($selection_settings_key, $selection_settings);
      }

      $elements['#field_reference_url'] = Url::fromRoute('datafield.field_reference', [
        'target_type' => $fieldSettings['entity_reference_type'],
        'selection_handler' => $fieldSettings["handler"],
        'selection_settings_key' => $selection_settings_key,
      ])->toString();
      $elements['#attached']['drupalSettings']['field_reference'][$field_reference] = $this->fieldReferenceSettings($fieldSettings['target_bundles']);
    }
    if ($cardinality != 1) {
      $subFormElements = Element::children($elements);
      foreach ($subFormElements as $delta) {
        if (is_numeric($delta)) {
          $childElements = Element::children($elements[$delta]);
          $element = [];
          foreach ($childElements as $child) {
            if (is_numeric($child)) {
              $element = $elements[$delta][$child];
            }
            else {
              $element[$child] = $elements[$delta][$child];
            }
          }
          unset($elements[$delta]);
          $elements[$delta] = $element;
        }
      }
    }
    $elements += [
      '#widgetDataFieldTable' => TRUE,
    ];
    $elements['#attached']['library'][] = 'datafield/shortcut';
    return $elements;
  }

  /**
   * Set drupal settings for search entity.
   *
   * @param string $target_bundle
   *   The bundle select or views.
   *
   * @return array
   *   The settings columns.
   */
  protected function fieldReferenceSettings(string $target_bundle): array {
    $settings = [
      'columns' => [
        ['field' => 'state', 'checkbox' => "true"],
      ],
    ];
    $searchKey = 'name';
    $checkView = explode(':', $target_bundle);
    if (!empty($checkView[1])) {
      $view = Views::getView($checkView[0]);
      $view->setDisplay($checkView[1]);
      $displayHandler = $view->displayHandlers->get($checkView[1]);
      $styleOptions = $displayHandler->getPlugin('style')->options['search_fields'];
      $styleOptions = array_filter($styleOptions);
      $searchKey = array_key_first($styleOptions);
      $listType = [
        'list_default',
        'options_select',
        'list_key',
        'options_buttons',
        'list_key',
      ];
      $settings['options'] = $displayHandler->getPlugin('row')->options;
      $fields = $displayHandler->getOption('fields');
      foreach ($fields as $fieldId => $field) {
        $type = $field["type"] ?? '';
        $typeSearch = in_array($type, $listType) ? 'select' : 'input';
        $settings['columns'][] = [
          'field' => $fieldId,
          'title' => !empty($field['label']) ? $field['label'] : $field["entity_field"] ?? '',
          'sortable' => "true",
          'filter-control' => $typeSearch,
        ];
      }
    }
    else {
      $settings['columns'][] = [
        'field' => $searchKey,
        'title' => $this->t('Name'),
        'sortable' => "true",
      ];
    }
    $settings['search_key'] = $searchKey;
    return $settings;
  }

}

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

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