You are here

field_config_cardinality.module in Field Config Cardinality 8

Same filename and directory in other branches
  1. 8.2 field_config_cardinality.module

Field_config_cardinality.module.

File

field_config_cardinality.module
View source
<?php

/**
 * @file
 * Field_config_cardinality.module.
 */
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Render\Element;
use Drupal\field_config_cardinality\Plugin\Field\FieldWidget\CardinalityMediaLibraryWidget;

/**
 * Implements hook_field_widget_info_alter().
 */
function field_config_cardinality_field_widget_info_alter(array &$info) {
  if (isset($info['media_library_widget'])) {
    $info['media_library_widget']['class'] = CardinalityMediaLibraryWidget::class;
  }
}

/**
 * Implements hook_form_alter().
 *
 * @param $form
 * @param FormStateInterface $form_state
 * @param $form_id
 */
function field_config_cardinality_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'field_config_edit_form') {

    /** @var \Drupal\field\Entity\FieldConfig $field_config */
    $field_config = $form_state
      ->getFormObject()
      ->getEntity();
    $cardinality = $field_config
      ->getFieldStorageDefinition()
      ->get('cardinality');
    $cardinality_config = $field_config
      ->getThirdPartySetting('field_config_cardinality', 'cardinality_config') ? $field_config
      ->getThirdPartySetting('field_config_cardinality', 'cardinality_config') : $cardinality;
    $form['cardinality_container'] = [
      // Reset #parents so the additional container does not appear.
      '#parents' => [],
      '#type' => 'fieldset',
      '#title' => t('Allowed number of values (Cardinality Instance)'),
      '#attributes' => [
        'class' => [
          'container-inline',
          'fieldgroup',
          'form-composite',
        ],
      ],
    ];
    $options = [
      'number' => t('Limited'),
      FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED => t('Unlimited'),
    ];
    if ($cardinality != -1) {
      unset($options['-1']);
    }
    $form['cardinality_container']['cardinality'] = [
      '#type' => 'select',
      '#title' => t('Allowed number of values'),
      '#title_display' => 'invisible',
      '#options' => $options,
      '#default_value' => $cardinality_config == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED ? FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED : 'number',
    ];
    $max = $cardinality != -1 ? $cardinality : TRUE;
    $form['cardinality_container']['cardinality_number'] = [
      '#type' => 'number',
      '#default_value' => $cardinality_config != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED ? $cardinality_config : 1,
      '#min' => 1,
      '#max' => $max,
      '#title' => t('Limit'),
      '#description' => t('Max number allowed:') . ($cardinality != -1 ? $cardinality : t('Unlimited')),
      '#title_display' => 'invisible',
      '#size' => 2,
      '#states' => [
        'visible' => [
          ':input[name="cardinality"]' => [
            'value' => 'number',
          ],
        ],
        'disabled' => [
          ':input[name="cardinality"]' => [
            'value' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
          ],
        ],
      ],
    ];
    $form['#entity_builders'][] = 'field_config_cardinality_form_builder';
  }
}

/**
 * Implements entity_builder.
 * see here: https://www.drupal.org/node/2334447 and https://www.drupal.org/node/2326151
 *
 * @param $entity_type
 * @param \Drupal\field\Entity\FieldConfig $config
 * @param $form
 * @param FormStateInterface $form_state
 */
function field_config_cardinality_form_builder($entity_type, \Drupal\field\Entity\FieldConfig $config, &$form, FormStateInterface $form_state) {
  if ($form_state
    ->getValue('cardinality') === 'number' && $form_state
    ->getValue('cardinality_number')) {
    $cardinality_config = $form_state
      ->getValue('cardinality_number');
  }
  else {
    $cardinality_config = $form_state
      ->getValue('cardinality');
  }
  if (!empty($cardinality_config)) {
    $config
      ->setThirdPartySetting('field_config_cardinality', 'cardinality_config', $cardinality_config);
  }
}

/**
 * Implements hook_form_alter().
 *
 * @param $elements
 * @param FormStateInterface $form_state
 * @param $context
 */
function field_config_cardinality_field_widget_multivalue_form_alter(&$elements, FormStateInterface $form_state, $context) {
  $cardinality_config = array();

  /** @var \Drupal\field\Entity\FieldConfig $field_definition */
  $field_definition = $context['items']
    ->getFieldDefinition();
  if (method_exists($field_definition, 'getOriginalId')) {
    $cardinality_config = $field_definition
      ->getThirdPartySetting('field_config_cardinality', 'cardinality_config');
    if (!empty($cardinality_config)) {
      $elements['#attributes']['data-fcc'] = $cardinality_config;
    }
  }

  // Implementation for multi managed_file
  if (!empty($elements['#type']) && $elements['#type'] == 'managed_file') {
    if (!empty($cardinality_config) && $cardinality_config >= 1) {
      if ($elements['#delta'] > $cardinality_config - 1) {
        $elements['#access'] = FALSE;
      }
    }
  }

  // Implementation for multi select type
  if (!empty($elements['#type']) && $elements['#type'] == 'select') {
    if (!empty($cardinality_config) && $cardinality_config >= 1) {
      $elements['#multiple'] = FALSE;
    }
  }
}

/**
 * Implements hook_preprocess_field_multiple_value_form()
 *
 * @param $variables
 */
function field_config_cardinality_preprocess_field_multiple_value_form(&$variables) {
  $element = $variables['element'];
  $variables['multiple'] = FALSE;
  if (!empty($element['#cardinality_multiple'])) {
    $variables['multiple'] = $element['#cardinality_multiple'];
  }
  else {
    if (!empty($element['#multiple'])) {
      $variables['multiple'] = $element['#multiple'];
    }
  }
  if ($variables['multiple'] == TRUE && isset($element['#attributes']['data-fcc'])) {
    $cardinality_config = $element['#attributes']['data-fcc'];
    if (!empty($cardinality_config)) {
      $order_class = $element['#field_name'] . '-delta-order';
      $rows = [];

      // Sort items according to '_weight' (needed when the form comes back after
      // preview or failed validation).
      $items = [];
      $variables['button'] = [];
      foreach (Element::children($element) as $key) {
        if (is_integer($key)) {
          $items[] =& $element[$key];
        }
      }
      if (count($items) <= $cardinality_config - 1 || $cardinality_config == '-1') {
        $variables['button'] =& $element['add_more'];
      }
      usort($items, '_field_multiple_value_form_sort_helper');

      // Add the items as table rows.
      foreach ($items as $key => $item) {
        if (is_numeric($key) && $key <= $cardinality_config - 1 || $cardinality_config == '-1') {
          $item['_weight']['#attributes']['class'] = [
            $order_class,
          ];

          // Remove weight form element from item render array so it can be rendered
          // in a separate table column.
          $delta_element = $item['_weight'];
          unset($item['_weight']);
          $cells = [
            [
              'data' => '',
              'class' => [
                'field-multiple-drag',
              ],
            ],
            [
              'data' => $item,
            ],
            [
              'data' => $delta_element,
              'class' => [
                'delta-order',
              ],
            ],
          ];
          $rows[] = [
            'data' => $cells,
            'class' => [
              'draggable',
            ],
          ];
        }
      }
      $variables['table']['#rows'] = $rows;
    }
  }
}