You are here

function _search_api_admin_get_fields in Search API 7

Helper function for building the field list for an index.

Deprecated

Use SearchApiIndex::getFields() instead.

File

./search_api.admin.inc, line 2004
Administration page callbacks for the Search API module.

Code

function _search_api_admin_get_fields(SearchApiIndex $index, EntityMetadataWrapper $wrapper) {
  $fields = empty($index->options['fields']) ? array() : $index->options['fields'];
  $additional = array();
  $entity_types = entity_get_info();

  // First we need all already added prefixes.
  $added = array();
  foreach (array_keys($fields) as $key) {
    $key = substr($key, 0, strrpos($key, ':'));
    $added[$key] = TRUE;
  }

  // Then we walk through all properties and look if they are already contained
  // in one of the arrays. Since this uses an iterative instead of a recursive
  // approach, it is a bit complicated, with three arrays tracking the current
  // depth.
  // A wrapper for a specific field name prefix, e.g. 'user:' mapped to the user
  // wrapper
  $wrappers = array(
    '' => $wrapper,
  );

  // Display names for the prefixes
  $prefix_names = array(
    '' => '',
  );

  // The list nesting level for entities with a certain prefix
  $nesting_levels = array(
    '' => 0,
  );
  $types = search_api_default_field_types();
  $flat = array();
  while ($wrappers) {
    foreach ($wrappers as $prefix => $wrapper) {
      $prefix_name = $prefix_names[$prefix];

      // Deal with lists of entities.
      $nesting_level = $nesting_levels[$prefix];
      $type_prefix = str_repeat('list<', $nesting_level);
      $type_suffix = str_repeat('>', $nesting_level);
      if ($nesting_level) {
        $info = $wrapper
          ->info();

        // The real nesting level of the wrapper, not the accumulated one.
        $level = search_api_list_nesting_level($info['type']);
        for ($i = 0; $i < $level; ++$i) {
          $wrapper = $wrapper[0];
        }
      }

      // Now look at all properties.
      foreach ($wrapper as $property => $value) {
        $info = $value
          ->info();

        // We hide the complexity of multi-valued types from the user here.
        $type = search_api_extract_inner_type($info['type']);

        // Treat Entity API type "token" as our "string" type.
        // Also let text fields with limited options be of type "string" by
        // default.
        if ($type == 'token' || $type == 'text' && !empty($info['options list'])) {

          // Inner type is changed to "string".
          $type = 'string';

          // Set the field type accordingly.
          $info['type'] = search_api_nest_type('string', $info['type']);
        }
        $info['type'] = $type_prefix . $info['type'] . $type_suffix;
        $key = $prefix . $property;
        if (isset($types[$type]) || isset($entity_types[$type])) {
          if (isset($fields[$key])) {

            // This field is already known in the index configuration.
            $fields[$key]['name'] = $prefix_name . $info['label'];
            $fields[$key]['description'] = empty($info['description']) ? NULL : $info['description'];
            $flat[$key] = $fields[$key];

            // Update its type.
            if (isset($entity_types[$type])) {

              // Always enforce the proper entity type.
              $flat[$key]['type'] = $info['type'];
            }
            else {

              // Else, only update the nesting level.
              $set_type = search_api_extract_inner_type(isset($flat[$key]['real_type']) ? $flat[$key]['real_type'] : $flat[$key]['type']);
              $flat[$key]['type'] = $info['type'];
              $flat[$key]['real_type'] = search_api_nest_type($set_type, $info['type']);
            }
          }
          else {
            $flat[$key] = array(
              'name' => $prefix_name . $info['label'],
              'description' => empty($info['description']) ? NULL : $info['description'],
              'type' => $info['type'],
              'boost' => '1.0',
              'indexed' => FALSE,
            );
          }
        }
        if (empty($types[$type])) {
          if (isset($added[$key])) {

            // Visit this entity/struct in a later iteration.
            $wrappers[$key . ':'] = $value;
            $prefix_names[$key . ':'] = $prefix_name . $info['label'] . ' » ';
            $nesting_levels[$key . ':'] = search_api_list_nesting_level($info['type']);
          }
          else {
            $name = $prefix_name . $info['label'];

            // Add machine names to discern fields with identical labels.
            if (isset($used_names[$name])) {
              if ($used_names[$name] !== FALSE) {
                $additional[$used_names[$name]] .= ' [' . $used_names[$name] . ']';
                $used_names[$name] = FALSE;
              }
              $name .= ' [' . $key . ']';
            }
            $additional[$key] = $name;
            $used_names[$name] = $key;
          }
        }
      }
      unset($wrappers[$prefix]);
    }
  }
  $options = array();
  $options['fields'] = $flat;
  $options['additional fields'] = $additional;
  return $options;
}