datafield-1.x-dev/src/Plugin/Field/FieldFormatter/Base.php

src/Plugin/Field/FieldFormatter/Base.php
<?php

namespace Drupal\datafield\Plugin\Field\FieldFormatter;

use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\datafield\Plugin\DataFieldFormatterPluginManager;
use Drupal\datafield\Plugin\DataFieldTypePluginManager;
use Drupal\datafield\Plugin\Field\FieldType\DataFieldItem;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Base class for data field formatters.
 */
abstract class Base extends FormatterBase {

  /**
   * Constructs a FormatterBase object.
   *
   * @param string $plugin_id
   *   The plugin_id for the formatter.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
   *   The definition of the field to which the formatter is associated.
   * @param array $settings
   *   The formatter settings.
   * @param string $label
   *   The formatter label display setting.
   * @param string $view_mode
   *   The view mode.
   * @param array $third_party_settings
   *   Any third party settings.
   * @param \Drupal\datafield\Plugin\DataFieldTypePluginManager $pluginType
   *   Plugin data type service.
   * @param \Drupal\datafield\Plugin\DataFieldFormatterPluginManager $pluginFormatter
   *   Plugin data formatter service.
   */
  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, protected DataFieldTypePluginManager $pluginType, protected DataFieldFormatterPluginManager $pluginFormatter) {
    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $plugin_id, $plugin_definition, $configuration['field_definition'],
      $configuration['settings'], $configuration['label'],
      $configuration['view_mode'], $configuration['third_party_settings'],
      $container->get('plugin.manager.data_field.type'),
      $container->get('plugin.manager.data_field.formatter'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings(): array {
    $default = [
      'formatter_settings' => [],
      'ajax' => FALSE,
      'custom_class' => '',
      'line_operations' => FALSE,
      'form_format_table' => FALSE,
    ];
    return $default + parent::defaultSettings();
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state): array {
    $settings = $this->getSetting('formatter_settings');
    $fieldSettings = $this->getFieldSettings();
    $types = DataFieldItem::subfieldTypes();
    $subfields = $this->getFieldSetting('columns');
    $field_name = $this->fieldDefinition->getName();
    if (!empty($settings) && count($subfields) == count($settings)) {
      uasort($settings, [
        'Drupal\Component\Utility\SortArray',
        'sortByWeightElement',
      ]);
      $subfields = $settings;
    }
    $element = [
      'ajax' => [
        '#title' => $this->t('Load data with ajax'),
        '#description' => $this->t('Use ajax to load big data'),
        '#type' => 'checkbox',
        '#default_value' => $this->getSetting('ajax'),
      ],
      'custom_class' => [
        '#title' => $this->t('Set table class'),
        '#type' => 'textfield',
        '#default_value' => $this->getSetting('custom_class'),
      ],
      'line_operations' => [
        '#title' => $this->t('Show operations'),
        '#type' => 'checkbox',
        '#default_value' => $this->getSetting('line_operations'),
      ],
      'form_format_table' => [
        '#title' => $this->t('Format table in add / edit form'),
        '#type' => 'checkbox',
        '#default_value' => $this->getSetting('form_format_table'),
      ],
    ];
    $formatterTypes = $this->pluginType->getDefinitions();
    $default_formatter = [];
    foreach ($formatterTypes as $formatter_type) {
      $default_formatter[$formatter_type['id']] = $formatter_type['default_formatter'];
    }
    $formatter_types = $this->pluginFormatter->getDefinitions();
    $formatterList = $this->pluginFormatter->getDefinitions();
    foreach ($formatter_types as $formatter_type) {
      foreach ($formatter_type['field_types'] as $type) {
        $option_formatter[$type][$formatter_type['id']] = $formatter_type['label'];
      }
    }
    // General settings.
    foreach (array_keys($subfields) as $subfield) {
      $item = $fieldSettings["columns"][$subfield];
      $type = $item['type'];
      $title = $item['name'] . ' - ' . $types[$type];
      $formatter_type = $settings[$subfield]['format_type'] ?? $default_formatter[$type];
      if (in_array($type, ['datetime_iso8601', 'date'])) {
        switch ($item["datetime_type"]) {
          case 'time':
          case 'week':
          case 'month':
            if (empty($settings[$subfield]["format_type"])) {
              $formatter_type = $default_formatter["string"];
            }
            $type = 'string';
            break;

          case 'year':
            if (empty($settings[$subfield]["format_type"])) {
              $formatter_type = $default_formatter["integer"];
            }
            $type = 'integer';
            break;
        }
      }
      $field_settings = $this->getFieldSetting('field_settings');
      if (!empty($field_settings[$subfield]['list'])) {
        $title .= ' (' . $this->t('list') . ')';
      }
      $form['#storage_settings'] = $item;
      $form['#field_settings'] = $field_settings[$subfield] ?? [];
      $form['#field_name'] = $field_name;
      $form['#settings'] = $settings[$subfield] ?? [];
      $form['#machine_name'] = $subfield;
      $formatter_settings = [
        'hidden' => [
          '#type' => 'checkbox',
          '#title' => $this->t('Hidden'),
          '#default_value' => $settings[$subfield]['hidden'] ?? FALSE,
        ],
        'show_label' => [
          '#type' => 'checkbox',
          '#title' => $this->t('Show label'),
          '#default_value' => $settings[$subfield]['show_label'] ?? FALSE,
        ],
      ];
      if (!empty($formatterList[$formatter_type])) {
        $plugin = $this->pluginFormatter->createInstance($formatter_type);
        $formatter_settings += $plugin->settingsForm($form, $form_state) ?? [];
      }
      $options = $option_formatter[$type] ?? [];
      $element['formatter_settings'][$subfield] = [
        '#title' => $title,
        '#type' => 'details',
        'format_type' => [
          '#type' => 'select',
          '#title' => $this->t('Formatter type'),
          '#description' => $this->t('Save and back again to get options.'),
          '#options' => $options,
          '#empty_option' => $this->t('- Select -'),
          '#default_value' => $formatter_type,
        ],
        'weight' => [
          '#type' => 'weight',
          '#title' => $this->t('Weight for fields'),
          '#default_value' => $settings[$subfield]['weight'] ?? 0,
          '#weight' => 20,
        ],
      ] + $formatter_settings;

    }

    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public function settingsSummary(): array {
    $settings = $this->getSetting('formatter_settings');
    $fieldSettings = $this->getFieldSettings();

    $subfield_types = DataFieldItem::subfieldTypes();
    $formatterTypes = $this->pluginType->getDefinitions();
    $formatterList = $this->pluginFormatter->getDefinitions();
    $default_formatter = [];
    foreach ($formatterTypes as $formatter_type) {
      $default_formatter[$formatter_type['id']] = $formatter_type['default_formatter'];
    }
    $summary = [];
    foreach ($fieldSettings["columns"] as $subfield => $item) {
      $subfield_type = $item['type'];
      if (empty($settings[$subfield]) || empty($fieldSettings["field_settings"])) {
        continue;
      }
      $formatter_type = $settings[$subfield]['format_type'] ?: $default_formatter[$subfield_type];
      if (empty($formatterList[$formatter_type])) {
        continue;
      }
      $plugin = $this->pluginFormatter->createInstance($formatter_type);
      if (!empty($fieldSettings["field_settings"][$subfield]["label"])) {
        $summary[] = new FormattableMarkup('<b>@subfield - @subfield_type@list</b>', [
          '@subfield' => $fieldSettings["field_settings"][$subfield]["label"],
          '@subfield_type' => strtolower($subfield_types[$subfield_type]),
          '@list' => !empty($fieldSettings["field_settings"][$subfield]["list"]) ? ' (' . $this->t('list') . ')' : '',
        ]);
      }
      if (isset($settings[$subfield]['hidden'])) {
        $summary[] = $this->t('Hidden: @value', ['@value' => $settings[$subfield]['hidden'] ? $this->t('yes') : $this->t('no')]);
      }
      if (method_exists($plugin, 'settingsSummary')) {
        $settingsSummary = $settings[$subfield];
        if (!empty($fieldSettings['field_settings'][$subfield])) {
          $settingsSummary += $fieldSettings['field_settings'][$subfield];
        }
        $summary = [...$summary, ...$plugin->settingsSummary($settingsSummary)];
      }
    }

    return $summary;
  }

  /**
   * {@inheritdoc}
   */
  public function view(FieldItemListInterface $items, $langcode = NULL): array {
    $elements = [];
    $settings = $this->getSettings();
    if (!$items->isEmpty()) {
      // A field may appear multiple times in a single view. Since items are
      // passed by reference we need to ensure they are processed only once.
      $items = clone $items;
      $this->prepareItems($items, $langcode);
      $elements = parent::view($items, $langcode);
    }
    elseif (!empty($settings['line_operations'])) {
      $elements = parent::view($items, $langcode);
    }
    return $elements;
  }

  /**
   * Prepare field items.
   *
   * @param \Drupal\Core\Field\FieldItemListInterface $items
   *   List of field items.
   * @param string $langcode
   *   Language code.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Core\Entity\EntityMalformedException|\Drupal\Component\Plugin\Exception\PluginException
   */
  protected function prepareItems(FieldItemListInterface $items, $langcode = NULL): void {
    $fieldSettings = $this->getFieldSettings();
    $settings = $this->getSettings();
    $setting = $settings['formatter_settings'];
    $formatterSettings = $this->getSetting('formatter_settings');
    $columns = $fieldSettings['columns'];
    $subfields = !empty($settings['formatter_settings']) ? $settings['formatter_settings'] : $columns;
    uasort($subfields, ['Drupal\Component\Utility\SortArray', 'sortByWeightElement']);
    $formatterTypes = $this->pluginType->getDefinitions();
    $default_formatter = [];
    foreach ($formatterTypes as $formatter_type) {
      $default_formatter[$formatter_type['id']] = $formatter_type['default_formatter'];
    }

    foreach ($items as $delta => $item) {
      foreach (array_keys($subfields) as $subfield) {
        if (empty($columns[$subfield]) || !empty($setting[$subfield]["hidden"])) {
          continue;
        }
        $field_setting = $fieldSettings["field_settings"][$subfield];
        $value_original = $item->{$subfield};
        if (!empty($field_setting['list']) && !empty($field_setting['allowed_values'])) {
          // @todo Remove the fallback in 5.x.
          $display_key = $setting['key'] ?? FALSE;
          if (!$display_key) {
            // Replace the value with its label if possible.
            $item->{$subfield} = $field_setting['allowed_values'][$item->{$subfield}] ?? NULL;
          }
        }
        $formatter_type = $default_formatter[$columns[$subfield]['type']];

        $plugin = $this->pluginFormatter->createInstance($setting[$subfield]['format_type'] ?? $formatter_type);
        $value = $item->{$subfield};
        $viewItem = (object) [
          'value' => $value['value'] ?? $value,
          'value_original' => $value_original,
          'field_setting' => $field_setting,
          'settings' => $formatterSettings[$subfield] ?? [],
          'storage' => $fieldSettings["columns"][$subfield],
          'entity' => $items->getEntity(),
          'field_name' => $items->getFieldDefinition()->getName(),
          'machine_name' => $subfield,
        ];
        $item->{$subfield} = $plugin->viewElements($viewItem, $langcode);
      }
      $items[$delta] = $item;
    }
  }

  /**
   * Check permission Operation.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity to check ownership.
   * @param string $fieldName
   *   The field name for permission check.
   *
   * @return bool
   *   TRUE if the user has the required permission, FALSE otherwise.
   */
  public static function checkPermissionOperation($entity, $fieldName): bool {
    $user = \Drupal::currentUser();
    // Check administrator role first for quick exit.
    if (in_array('administrator', $user->getRoles())) {
      return TRUE;
    }
    // Define permissions to check.
    $permissions = [
      'bypass node access',
      'administer nodes',
      'create ' . $fieldName,
      'edit ' . $fieldName,
      'edit own ' . $fieldName,
    ];
    // Check general permissions.
    foreach ($permissions as $permission) {
      if ($user->hasPermission($permission)) {
        return TRUE;
      }
    }
    // Check ownership if entity is not a user entity.
    if ($entity->getEntityTypeId() !== 'user' && method_exists($entity, 'getOwnerId')) {
      $uid = $entity->getOwnerId();
      if ($uid && $uid == $user->id() && $user->hasPermission("edit own $fieldName")) {
        return TRUE;
      }
    }
    return FALSE;
  }

}

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

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