You are here

function search_api_extract_fields in Search API 7

Extracts specific field values from an EntityMetadataWrapper object.

Parameters

EntityMetadataWrapper $wrapper: The wrapper from which to extract fields.

array $fields: The fields to extract, as stored in an index. I.e., the array keys are field names, the values are arrays with at least a "type" key present.

array $value_options: An array of options that should be passed to the EntityMetadataWrapper::value() method (see there).

Return value

array The $fields array with additional "value" and "original_type" keys set.

4 calls to search_api_extract_fields()
SearchApiAlterAddAggregation::alterItems in includes/callback_add_aggregation.inc
Alter items before indexing.
SearchApiHighlight::getFulltextFields in includes/processor_highlight.inc
Retrieves the fulltext data of a result.
SearchApiIndex::index in includes/index_entity.inc
Indexes items on this index.
SearchApiViewsQuery::extractFields in contrib/search_api_views/includes/query.inc
Helper function for extracting all necessary fields from a result item.

File

./search_api.module, line 2455
Provides a flexible framework for implementing search services.

Code

function search_api_extract_fields(EntityMetadataWrapper $wrapper, array $fields, array $value_options = array()) {
  $value_options += array(
    'identifier' => TRUE,
  );

  // If $wrapper is a list of entities, we have to aggregate their field values.
  $wrapper_info = $wrapper
    ->info();
  if (search_api_is_list_type($wrapper_info['type'])) {
    foreach ($fields as &$info) {
      $info['value'] = array();
      $info['original_type'] = $info['type'];
    }
    unset($info);
    try {
      foreach ($wrapper as $w) {
        $nested_fields = search_api_extract_fields($w, $fields, $value_options);
        foreach ($nested_fields as $field => $info) {
          if (isset($info['value'])) {
            $fields[$field]['value'][] = $info['value'];
          }
          if (isset($info['original_type'])) {
            $fields[$field]['original_type'] = $info['original_type'];
          }
        }
      }
    } catch (EntityMetadataWrapperException $e) {

      // Catch exceptions caused by not set list values.
    }
    return $fields;
  }
  $nested = array();
  $entity_infos = entity_get_info();
  foreach ($fields as $field => &$info) {
    $pos = strpos($field, ':');
    if ($pos === FALSE) {

      // Set "defaults" in case an error occurs later.
      $info['value'] = NULL;
      $info['original_type'] = $info['type'];
      if (isset($wrapper->{$field})) {
        try {

          // Set the original type according to the field wrapper's info.
          $property_info = $wrapper->{$field}
            ->info();
          $info['original_type'] = $property_info['type'];

          // Extract the basic value from the field wrapper.
          $info['value'] = $wrapper->{$field}
            ->value($value_options);

          // For entities, we need to take care to differentiate between
          // entities with ID 0 and empty fields. In the latter case, the
          // wrapper's value() method returns, when called with "identifier =
          // TRUE", FALSE instead of the (more logical) NULL.
          $is_entity = isset($entity_infos[search_api_extract_inner_type($property_info['type'])]);
          if ($is_entity && $info['value'] === FALSE) {
            $info['value'] = NULL;
          }

          // If we index the field as fulltext, we also include the entity label
          // or option list label, if applicable.
          if (search_api_is_text_type($info['type']) && isset($info['value'])) {
            if ($wrapper->{$field}
              ->optionsList('view')) {
              _search_api_add_option_values($info['value'], $wrapper->{$field}
                ->optionsList('view'));
            }
            elseif ($is_entity) {
              $info['value'] = _search_api_extract_entity_value($wrapper->{$field}, TRUE);
            }
          }
        } catch (EntityMetadataWrapperException $e) {

          // This might happen for entity-typed properties that are NULL, e.g.,
          // for comments without parent.
        }
      }
    }
    else {
      list($prefix, $key) = explode(':', $field, 2);
      $nested[$prefix][$key] = $info;
    }
  }
  unset($info);
  foreach ($nested as $prefix => $nested_fields) {
    if (isset($wrapper->{$prefix})) {
      $nested_fields = search_api_extract_fields($wrapper->{$prefix}, $nested_fields, $value_options);
      foreach ($nested_fields as $field => $info) {
        $fields["{$prefix}:{$field}"] = $info;
      }
    }
    else {
      foreach ($nested_fields as &$info) {
        $info['value'] = NULL;
        $info['original_type'] = $info['type'];
      }
    }
  }
  return $fields;
}