You are here

public function ViewEditForm::getFormBucket in Drupal 10

Same name and namespace in other branches
  1. 8 core/modules/views_ui/src/ViewEditForm.php \Drupal\views_ui\ViewEditForm::getFormBucket()
  2. 9 core/modules/views_ui/src/ViewEditForm.php \Drupal\views_ui\ViewEditForm::getFormBucket()

Add information about a section to a display.

File

core/modules/views_ui/src/ViewEditForm.php, line 969

Class

ViewEditForm
Form controller for the Views edit form.

Namespace

Drupal\views_ui

Code

public function getFormBucket(ViewUI $view, $type, $display) {
  $executable = $view
    ->getExecutable();
  $executable
    ->setDisplay($display['id']);
  $executable
    ->initStyle();
  $types = $executable
    ->getHandlerTypes();
  $build = [
    '#theme_wrappers' => [
      'views_ui_display_tab_bucket',
    ],
  ];
  $build['#overridden'] = FALSE;
  $build['#defaulted'] = FALSE;
  $build['#name'] = $type;
  $build['#title'] = $types[$type]['title'];
  $rearrange_url = Url::fromRoute('views_ui.form_rearrange', [
    'js' => 'nojs',
    'view' => $view
      ->id(),
    'display_id' => $display['id'],
    'type' => $type,
  ]);
  $class = 'icon compact rearrange';

  // Different types now have different rearrange forms, so we use this switch
  // to get the right one.
  switch ($type) {
    case 'filter':

      // The rearrange form for filters contains the and/or UI, so override
      // the used path.
      $rearrange_url = Url::fromRoute('views_ui.form_rearrange_filter', [
        'js' => 'nojs',
        'view' => $view
          ->id(),
        'display_id' => $display['id'],
      ]);

      // TODO: Add another class to have another symbol for filter rearrange.
      $class = 'icon compact rearrange';
      break;
    case 'field':

      // Fetch the style plugin info so we know whether to list fields or not.
      $style_plugin = $executable->style_plugin;
      $uses_fields = $style_plugin && $style_plugin
        ->usesFields();
      if (!$uses_fields) {
        $build['fields'][] = [
          '#markup' => $this
            ->t('The selected style or row format does not use fields.'),
          '#theme_wrappers' => [
            'views_ui_container',
          ],
          '#attributes' => [
            'class' => [
              'views-display-setting',
            ],
          ],
        ];
        return $build;
      }
      break;
    case 'header':
    case 'footer':
    case 'empty':
      if (!$executable->display_handler
        ->usesAreas()) {
        $build[$type][] = [
          '#markup' => $this
            ->t('The selected display type does not use @type plugins', [
            '@type' => $type,
          ]),
          '#theme_wrappers' => [
            'views_ui_container',
          ],
          '#attributes' => [
            'class' => [
              'views-display-setting',
            ],
          ],
        ];
        return $build;
      }
      break;
  }

  // Create an array of actions to pass to links template.
  $actions = [];
  $count_handlers = count($executable->display_handler
    ->getHandlers($type));

  // Create the add text variable for the add action.
  $add_text = $this
    ->t('Add <span class="visually-hidden">@type</span>', [
    '@type' => $types[$type]['ltitle'],
  ]);
  $actions['add'] = [
    'title' => $add_text,
    'url' => Url::fromRoute('views_ui.form_add_handler', [
      'js' => 'nojs',
      'view' => $view
        ->id(),
      'display_id' => $display['id'],
      'type' => $type,
    ]),
    'attributes' => [
      'class' => [
        'icon compact add',
        'views-ajax-link',
      ],
      'id' => 'views-add-' . $type,
    ],
  ];
  if ($count_handlers > 0) {

    // Create the rearrange text variable for the rearrange action.
    $rearrange_text = $type == 'filter' ? $this
      ->t('And/Or Rearrange <span class="visually-hidden">filter criteria</span>') : $this
      ->t('Rearrange <span class="visually-hidden">@type</span>', [
      '@type' => $types[$type]['ltitle'],
    ]);
    $actions['rearrange'] = [
      'title' => $rearrange_text,
      'url' => $rearrange_url,
      'attributes' => [
        'class' => [
          $class,
          'views-ajax-link',
        ],
        'id' => 'views-rearrange-' . $type,
      ],
    ];
  }

  // Render the array of links
  $build['#actions'] = [
    '#type' => 'dropbutton',
    '#links' => $actions,
    '#attributes' => [
      'class' => [
        'views-ui-settings-bucket-operations',
      ],
    ],
  ];
  if (!$executable->display_handler
    ->isDefaultDisplay()) {
    if (!$executable->display_handler
      ->isDefaulted($types[$type]['plural'])) {
      $build['#overridden'] = TRUE;
    }
    else {
      $build['#defaulted'] = TRUE;
    }
  }
  static $relationships = NULL;
  if (!isset($relationships)) {

    // Get relationship labels.
    $relationships = [];
    foreach ($executable->display_handler
      ->getHandlers('relationship') as $id => $handler) {
      $relationships[$id] = $handler
        ->adminLabel();
    }
  }

  // Filters can now be grouped so we do a little bit extra:
  $groups = [];
  $grouping = FALSE;
  if ($type == 'filter') {
    $group_info = $executable->display_handler
      ->getOption('filter_groups');

    // If there is only one group but it is using the "OR" filter, we still
    // treat it as a group for display purposes, since we want to display the
    // "OR" label next to items within the group.
    if (!empty($group_info['groups']) && (count($group_info['groups']) > 1 || current($group_info['groups']) == 'OR')) {
      $grouping = TRUE;
      $groups = [
        0 => [],
      ];
    }
  }
  $build['fields'] = [];
  foreach ($executable->display_handler
    ->getOption($types[$type]['plural']) as $id => $field) {

    // Build the option link for this handler ("Node: ID = article").
    $build['fields'][$id] = [];
    $build['fields'][$id]['#theme'] = 'views_ui_display_tab_setting';
    $handler = $executable->display_handler
      ->getHandler($type, $id);
    if ($handler
      ->broken()) {
      $build['fields'][$id]['#class'][] = 'broken';
      $field_name = $handler
        ->adminLabel();
      $build['fields'][$id]['#link'] = Link::fromTextAndUrl($field_name, new Url('views_ui.form_handler', [
        'js' => 'nojs',
        'view' => $view
          ->id(),
        'display_id' => $display['id'],
        'type' => $type,
        'id' => $id,
      ], [
        'attributes' => [
          'class' => [
            'views-ajax-link',
          ],
        ],
      ]))
        ->toString();
      continue;
    }
    $field_name = $handler
      ->adminLabel(TRUE);
    if (!empty($field['relationship']) && !empty($relationships[$field['relationship']])) {
      $field_name = '(' . $relationships[$field['relationship']] . ') ' . $field_name;
    }
    $description = $handler
      ->adminSummary();
    $link_text = $field_name . (empty($description) ? '' : " ({$description})");
    $link_attributes = [
      'class' => [
        'views-ajax-link',
      ],
    ];
    if (!empty($field['exclude'])) {
      $link_attributes['class'][] = 'views-field-excluded';

      // Add a [hidden] marker, if the field is excluded.
      $link_text .= ' [' . $this
        ->t('hidden') . ']';
    }
    $build['fields'][$id]['#link'] = Link::fromTextAndUrl($link_text, new Url('views_ui.form_handler', [
      'js' => 'nojs',
      'view' => $view
        ->id(),
      'display_id' => $display['id'],
      'type' => $type,
      'id' => $id,
    ], [
      'attributes' => $link_attributes,
    ]))
      ->toString();
    $build['fields'][$id]['#class'][] = Html::cleanCssIdentifier($display['id'] . '-' . $type . '-' . $id);
    if ($executable->display_handler
      ->useGroupBy() && $handler
      ->usesGroupBy()) {
      $build['fields'][$id]['#settings_links'][] = Link::fromTextAndUrl(new FormattableMarkup('<span class="label">@text</span>', [
        '@text' => $this
          ->t('Aggregation settings'),
      ]), new Url('views_ui.form_handler_group', [
        'js' => 'nojs',
        'view' => $view
          ->id(),
        'display_id' => $display['id'],
        'type' => $type,
        'id' => $id,
      ], [
        'attributes' => [
          'class' => [
            'views-button-configure',
            'views-ajax-link',
          ],
          'title' => $this
            ->t('Aggregation settings'),
        ],
      ]))
        ->toString();
    }
    if ($handler
      ->hasExtraOptions()) {
      $build['fields'][$id]['#settings_links'][] = Link::fromTextAndUrl(new FormattableMarkup('<span class="label">@text</span>', [
        '@text' => $this
          ->t('Settings'),
      ]), new Url('views_ui.form_handler_extra', [
        'js' => 'nojs',
        'view' => $view
          ->id(),
        'display_id' => $display['id'],
        'type' => $type,
        'id' => $id,
      ], [
        'attributes' => [
          'class' => [
            'views-button-configure',
            'views-ajax-link',
          ],
          'title' => $this
            ->t('Settings'),
        ],
      ]))
        ->toString();
    }
    if ($grouping) {
      $gid = $handler->options['group'];

      // Show in default group if the group does not exist.
      if (empty($group_info['groups'][$gid])) {
        $gid = 0;
      }
      $groups[$gid][] = $id;
    }
  }

  // If using grouping, re-order fields so that they show up properly in the list.
  if ($type == 'filter' && $grouping) {
    $store = $build['fields'];
    $build['fields'] = [];
    foreach ($groups as $gid => $contents) {

      // Display an operator between each group.
      if (!empty($build['fields'])) {
        $build['fields'][] = [
          '#theme' => 'views_ui_display_tab_setting',
          '#class' => [
            'views-group-text',
          ],
          '#link' => $group_info['operator'] == 'OR' ? $this
            ->t('OR') : $this
            ->t('AND'),
        ];
      }

      // Display an operator between each pair of filters within the group.
      $keys = array_keys($contents);
      $last = end($keys);
      foreach ($contents as $key => $pid) {
        if ($key != $last) {
          $operator = $group_info['groups'][$gid] == 'OR' ? $this
            ->t('OR') : $this
            ->t('AND');
          $store[$pid]['#link'] = new FormattableMarkup('@link <span>@operator</span>', [
            '@link' => $store[$pid]['#link'],
            '@operator' => $operator,
          ]);
        }
        $build['fields'][$pid] = $store[$pid];
      }
    }
  }
  return $build;
}