You are here

protected function IndexFieldsForm::buildFieldsTable in Search API 8

Builds the form fields for a set of fields.

Parameters

\Drupal\search_api\Item\FieldInterface[] $fields: List of fields to display.

Return value

array The build structure.

1 call to IndexFieldsForm::buildFieldsTable()
IndexFieldsForm::buildForm in src/Form/IndexFieldsForm.php
Form constructor.

File

src/Form/IndexFieldsForm.php, line 225

Class

IndexFieldsForm
Provides a form for configuring the fields of a search index.

Namespace

Drupal\search_api\Form

Code

protected function buildFieldsTable(array $fields) {
  $fallback_types = $this->dataTypeHelper
    ->getDataTypeFallbackMapping($this->entity);

  // If one of the unsupported types is actually used by the index, show a
  // warning.
  if ($fallback_types) {
    foreach ($fields as $field) {
      if (isset($fallback_types[$field
        ->getType()])) {
        $args = [
          ':url' => '#search-api-data-types-table',
        ];
        $warning = $this
          ->t("Some of the used data types aren't supported by the server's backend. See the <a href=\":url\">data types table</a> to find out which types are supported.", $args);
        $this->messenger
          ->addWarning($warning);
        break;
      }
    }
  }
  $types = [];
  $fulltext_types = [
    [
      'value' => 'text',
    ],
  ];

  // Add all data types with fallback "text" to fulltext types as well.
  foreach ($this->dataTypePluginManager
    ->getInstances() as $type_id => $type) {
    if (!$type
      ->isHidden()) {
      $types[$type_id] = $type
        ->label();
    }
    if ($type
      ->getFallbackType() == 'text') {
      $fulltext_types[] = [
        'value' => $type_id,
      ];
    }
  }
  $additional_factors = [];
  foreach ($fields as $field) {
    $additional_factors[] = $field
      ->getBoost();
  }
  $boosts = Utility::getBoostFactors($additional_factors);
  $build = [
    '#type' => 'details',
    '#open' => TRUE,
    '#theme' => 'search_api_admin_fields_table',
    '#parents' => [],
    '#header' => [
      $this
        ->t('Label'),
      $this
        ->t('Machine name'),
      [
        'data' => $this
          ->t('Property path'),
        'class' => [
          RESPONSIVE_PRIORITY_LOW,
        ],
      ],
      $this
        ->t('Type'),
      $this
        ->t('Boost'),
      [
        'data' => $this
          ->t('Operations'),
        'colspan' => 2,
      ],
    ],
  ];
  uasort($fields, [
    $this->fieldsHelper,
    'compareFieldLabels',
  ]);
  foreach ($fields as $key => $field) {
    $build['fields'][$key]['#access'] = !$field
      ->isHidden();
    $build['fields'][$key]['title'] = [
      '#type' => 'textfield',
      '#default_value' => $field
        ->getLabel() ?: $key,
      '#required' => TRUE,
      '#size' => 40,
    ];
    $build['fields'][$key]['id'] = [
      '#type' => 'textfield',
      '#default_value' => $key,
      '#required' => TRUE,
      '#size' => 35,
    ];
    $build['fields'][$key]['property_path'] = [
      '#markup' => Html::escape($field
        ->getPropertyPath()),
    ];
    if ($field
      ->getDescription()) {
      $build['fields'][$key]['description'] = [
        '#type' => 'value',
        '#value' => $field
          ->getDescription(),
      ];
    }
    $build['fields'][$key]['type'] = [
      '#type' => 'select',
      '#options' => $types,
      '#default_value' => $field
        ->getType(),
    ];
    if ($field
      ->isTypeLocked()) {
      $build['fields'][$key]['type']['#disabled'] = TRUE;
    }
    $build['fields'][$key]['boost'] = [
      '#type' => 'select',
      '#options' => $boosts,
      '#default_value' => Utility::formatBoostFactor($field
        ->getBoost()),
      '#states' => [
        'visible' => [
          ':input[name="fields[' . $key . '][type]"]' => $fulltext_types,
        ],
      ],
    ];
    $route_parameters = [
      'search_api_index' => $this->entity
        ->id(),
      'field_id' => $key,
    ];

    // Provide some invisible markup as default, if a link is missing, so we
    // don't break the table structure. (theme_search_api_admin_fields_table()
    // does not add empty cells.)
    $build['fields'][$key]['edit']['#markup'] = '<span></span>';
    try {
      if ($field
        ->getDataDefinition() instanceof ConfigurablePropertyInterface) {
        $build['fields'][$key]['edit'] = [
          '#type' => 'link',
          '#title' => $this
            ->t('Edit'),
          '#url' => Url::fromRoute('entity.search_api_index.field_config', $route_parameters),
          '#attributes' => [
            'class' => [
              'use-ajax',
            ],
            'data-dialog-type' => 'modal',
            'data-dialog-options' => Json::encode([
              'width' => 700,
            ]),
          ],
        ];
      }
    } catch (SearchApiException $e) {

      // Could not retrieve data definition. Since this almost certainly means
      // that the property isn't configurable, we can just ignore it here.
    }
    $build['fields'][$key]['remove']['#markup'] = '<span></span>';
    if (!$field
      ->isIndexedLocked()) {
      $build['fields'][$key]['remove'] = [
        '#type' => 'link',
        '#title' => $this
          ->t('Remove'),
        '#url' => Url::fromRoute('entity.search_api_index.remove_field', $route_parameters),
        '#attributes' => [
          'class' => [
            'use-ajax',
          ],
        ],
      ];
    }
  }
  return $build;
}