You are here

public function ContextualRangeFilterAssignmentForm::buildForm in Views Contextual Range Filter 8

Build the form.

Overrides ConfigFormBase::buildForm

File

src/Form/ContextualRangeFilterAssignmentForm.php, line 40

Class

ContextualRangeFilterAssignmentForm
Convert selected contextual filters to contextual range filters.

Namespace

Drupal\contextual_range_filter\Form

Code

public function buildForm(array $form, FormStateInterface $form_state) {
  $range_fields = [
    'date_field_names' => [],
    'numeric_field_names' => [],
    'string_field_names' => [],
  ];
  $class_path = 'Drupal\\views\\Plugin\\views\\argument';
  $argument_info = Views::pluginManager('argument')
    ->getDefinitions();
  foreach (Views::getAllViews() as $view) {
    $view_name = $view
      ->get('label');
    if (views_view_is_disabled($view)) {
      $view_name .= ' (' . $this
        ->t('disabled') . ')';
    }
    foreach ($view
      ->get('display') as $display) {
      if (!empty($display['display_options']['arguments'])) {
        foreach ($display['display_options']['arguments'] as $contextual_filter) {
          $plugin_id = $contextual_filter['plugin_id'];
          $class = $argument_info[$plugin_id]['class'];

          // Does this contextual filter class extend one of the base
          // contextual filter classes?
          // Note: lists have a class of Numeric or String, so nothing special
          // needs or can be done for lists...
          $is_date_handler = is_a($class, "{$class_path}\\Date", TRUE);
          $is_string_handler = is_a($class, "{$class_path}\\StringArgument", TRUE);

          // Anything that is not a date or string will be shown as numeric.
          $is_numeric_handler = !$is_date_handler && !$is_string_handler;
          if ($is_date_handler || $is_numeric_handler || $is_string_handler) {

            // For every View $display we get a number of fields.
            // Should we allow selection per display AND per field?
            // Currently we find, but don't add, the "duplicates".
            // @todo: Find something more human-readible than this.
            $title = "{$plugin_id}: " . $contextual_filter['id'];

            // @todo Taxonomy term depth has Views machine name
            // "taxonomy_term_data:tid", not "node:term_node_tid_depth".
            $machine_name = $contextual_filter['table'] . ':' . $contextual_filter['field'];
            if ($is_date_handler) {
              $title_used = isset($range_fields['date_field_names'][$machine_name][$title]);
              if (!$title_used || !in_array($view_name, $range_fields['date_field_names'][$machine_name][$title])) {
                $range_fields['date_field_names'][$machine_name][$title][] = $view_name;
              }
            }
            elseif ($is_numeric_handler) {
              $title_used = isset($range_fields['numeric_field_names'][$machine_name][$title]);
              if (!$title_used || !in_array($view_name, $range_fields['numeric_field_names'][$machine_name][$title])) {
                $range_fields['numeric_field_names'][$machine_name][$title][] = $view_name;
              }
            }
            elseif ($is_string_handler) {
              $title_used = isset($range_fields['string_field_names'][$machine_name][$title]);
              if (!$title_used || !in_array($view_name, $range_fields['string_field_names'][$machine_name][$title])) {
                $range_fields['string_field_names'][$machine_name][$title][] = $view_name;
              }
            }
          }
        }
      }
    }
  }
  $form['field_names'] = [
    '#type' => 'fieldset',
    '#title' => $this
      ->t('Select contextual filters to be converted to contextual range filters'),
  ];
  $config = $this->configFactory
    ->get('contextual_range_filter.settings');
  $labels = [
    $this
      ->t('date'),
    $this
      ->t('numeric'),
    $this
      ->t('string'),
  ];
  $label = reset($labels);
  foreach ($range_fields as $type => $data) {
    $options = [];
    foreach ($data as $machine_name => $view_names) {
      $title = key($view_names);
      $views_list = implode(', ', $view_names[$title]);
      $replace = [
        '%field' => $title,
        '@views' => $views_list,
      ];
      $options[$machine_name] = $this
        ->t('%field in view @views', $replace);
      $form['#view_names'][$machine_name] = $view_names;
    }
    $form['field_names'][$type] = [
      '#type' => 'checkboxes',
      '#title' => $this
        ->t('Select which of the below contextual <em>@label</em> filters should be converted to <em>@label range</em> filters:', [
        '@label' => $label,
      ]),
      '#default_value' => $config
        ->get($type) ?: [],
      '#options' => $options,
    ];
    $label = next($labels);
  }
  $form['actions']['note'] = [
    '#markup' => '<p><em>' . $this
      ->t('Caches will be cleared as part of this operation. This may take a while.') . '</em></p>',
    '#weight' => 1,
  ];
  return parent::buildForm($form, $form_state);
}