You are here

public function ViewsFieldFormatter::settingsForm in Views field formatter 8.2

Same name and namespace in other branches
  1. 8 src/Plugin/Field/FieldFormatter/ViewsFieldFormatter.php \Drupal\views_field_formatter\Plugin\Field\FieldFormatter\ViewsFieldFormatter::settingsForm()

Returns a form to configure settings for the formatter.

Invoked from \Drupal\field_ui\Form\EntityDisplayFormBase to allow administrators to configure the formatter. The field_ui module takes care of handling submitted form values.

Parameters

array $form: The form where the settings form is being included in.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

Return value

array The form elements for the formatter settings.

Overrides FormatterBase::settingsForm

File

src/Plugin/Field/FieldFormatter/ViewsFieldFormatter.php, line 111

Class

ViewsFieldFormatter
Class ViewsFieldFormatter.

Namespace

Drupal\views_field_formatter\Plugin\Field\FieldFormatter

Code

public function settingsForm(array $form, FormStateInterface $form_state) {
  $element = parent::settingsForm($form, $form_state);
  $settings = $this
    ->getSettings();

  // Get all views select options.
  $options = [];
  foreach (Views::getAllViews() as $view) {
    foreach ($view
      ->get('display') as $display) {
      $label = $view
        ->get('label');
      $options[$label][$view
        ->get('id') . '::' . $display['id']] = \sprintf('%s - %s', $label, $display['display_title']);
    }
  }

  // Early return if there is no views.
  if ([] === $options) {
    $element['help'] = [
      '#markup' => '<p>' . $this
        ->t('No available Views were found.') . '</p>',
    ];
    return $element;
  }
  $checked_arguments = \array_filter((array) $settings['arguments'], function ($argument) {
    return $argument['checked'];
  });

  // Make sure we only save arguments that are enabled.
  $settings['arguments'] = \array_values($checked_arguments);
  $this
    ->setSettings($settings);
  $ajax_arguments_count = 'ajax_arguments_count_' . $this->fieldDefinition
    ->getName();
  if ($form_state
    ->get($ajax_arguments_count) === NULL) {
    $form_state
      ->set($ajax_arguments_count, \count($checked_arguments));
  }

  // Ensure we clicked the Ajax button.
  // @todo Is there a better way to detect this ?
  $trigger = $form_state
    ->getTriggeringElement();
  if (\is_array($trigger['#array_parents']) && \end($trigger['#array_parents']) === 'addRow') {
    $form_state
      ->set($ajax_arguments_count, $form_state
      ->get($ajax_arguments_count) + 1);
  }
  $element['view'] = [
    '#title' => $this
      ->t('View'),
    '#description' => $this
      ->t("Select the view that will be displayed instead of the field's value."),
    '#type' => 'select',
    '#default_value' => $this
      ->getSetting('view'),
    '#options' => $options,
  ];
  $element['arguments'] = [
    '#prefix' => '<div id="ajax_form_table_arguments">',
    '#suffix' => '</div>',
    '#type' => 'table',
    '#header' => [
      '',
      $this
        ->t('Weight'),
      $this
        ->t('Argument index'),
      $this
        ->t('String or token'),
    ],
    '#tabledrag' => [
      [
        'action' => 'order',
        'relationship' => 'sibling',
        'group' => 'arguments-order-weight',
      ],
    ],
    '#caption' => $this
      ->t('Select,add and reorder the arguments that will be used by the selected
         view as contextual filters.
         To remove some rows, uncheck the checkbox and save.'),
  ];
  for ($i = 0; $i < $form_state
    ->get($ajax_arguments_count); $i++) {
    $element['arguments'][] = [
      'checked' => [
        '#type' => 'checkbox',
        '#title' => '',
        '#default_value' => $this
          ->getSettings()['arguments'][$i]['checked'],
      ],
      'weight' => [
        '#type' => 'weight',
        '#title' => $this
          ->t('Weight for @title', [
          '@title' => 'token',
        ]),
        '#title_display' => 'invisible',
        '#attributes' => [
          'class' => [
            'arguments-order-weight',
          ],
        ],
      ],
      'argument_index' => [
        '#markup' => $i,
      ],
      'token' => [
        '#type' => 'textfield',
        '#title' => 'Argument',
        '#description' => $this
          ->t('Use a static string or a Drupal token - You can temporary use <em>%value%</em> until a proper token is found.'),
        '#default_value' => $this
          ->getSettings()['arguments'][$i]['token'],
      ],
      '#attributes' => [
        'class' => [
          'draggable',
        ],
      ],
    ];
  }
  $element['addRow'] = [
    '#type' => 'button',
    '#button_type' => 'secondary',
    '#value' => t('Add a new argument'),
    '#ajax' => [
      'callback' => [
        $this,
        'ajaxAddRow',
      ],
      'event' => 'click',
      'wrapper' => 'ajax_form_table_arguments',
    ],
  ];
  $types = [
    'site',
    'user',
    'entity',
    'field',
    'date',
  ];
  switch ($this->fieldDefinition
    ->getTargetEntityTypeId()) {
    case 'taxonomy_term':
      $types[] = 'term';
      $types[] = 'vocabulary';
      break;
    default:
      $types[] = $this->fieldDefinition
        ->getTargetEntityTypeId();
      break;
  }
  $token = \Drupal::token();
  $info = $token
    ->getInfo();
  $available_token = \array_intersect_key($info['tokens'], \array_flip($types));
  $token_items = [];
  foreach ($available_token as $type => $tokens) {
    $item = [
      '#markup' => $this
        ->t('@type tokens', [
        '@type' => \ucfirst($type),
      ]),
      'children' => [],
    ];
    foreach ($tokens as $name => $info) {
      $info += [
        'description' => $this
          ->t('No description available'),
      ];
      $item['children'][$name] = \sprintf('[%s:%s] - %s: %s', $type, $name, $info['name'], $info['description']);
    }
    $token_items[$type] = $item;
  }
  $element['token_tree_link'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Available token replacements'),
    'description' => [
      '#markup' => $this
        ->t('To have more tokens, please install the <a href="@token">Token contrib module</a>.', [
        '@token' => 'https://drupal.org/project/token',
      ]),
    ],
  ];
  $element['token_tree_link']['list'] = [
    '#theme' => 'item_list',
    '#items' => $token_items,
    '#attributes' => [
      'class' => [
        'global-tokens',
      ],
    ],
  ];
  if (\Drupal::moduleHandler()
    ->moduleExists('token')) {
    $element['token_tree_link'] = [
      '#theme' => 'token_tree_link',
      '#token_types' => $types,
    ];
  }
  $element['hide_empty'] = [
    '#title' => $this
      ->t('Hide empty views'),
    '#description' => $this
      ->t('Do not display the field if the view is empty.'),
    '#type' => 'checkbox',
    '#default_value' => (bool) $this
      ->getSetting('hide_empty'),
  ];
  $element['multiple'] = [
    '#title' => $this
      ->t('Multiple'),
    '#description' => $this
      ->t('If the field is configured as multiple (<em>greater than one</em>),
         should we display a view per item ? If selected, there will be one view per item.'),
    '#type' => 'checkbox',
    '#default_value' => (bool) $this
      ->getSetting('multiple'),
  ];
  $element['implode_character'] = [
    '#title' => $this
      ->t('Concatenate arguments'),
    '#description' => $this
      ->t('If it is set, all arguments will be concatenated with the chosen character (<em>ex: a simple comma</em>)
         and sent as one argument. Empty to disable.'),
    '#type' => 'textfield',
    '#default_value' => $this
      ->getSetting('implode_character'),
  ];
  return $element;
}