You are here

protected function SearchApiFieldTrait::combineHighlightedValues in Search API 8

Combines raw field values with highlighted ones to get a complete set.

If highlighted field values are set on the result item, not all values might be included, but only the ones with matches. Since we still want to show all values, of course, we need to combine the highlighted values with the ones we extracted.

Parameters

array $extracted_values: All values for a field.

array $highlighted_values: A subset of field values that are highlighted.

Return value

array An array of normal and highlighted field values, avoiding duplicates as well as possible.

1 call to SearchApiFieldTrait::combineHighlightedValues()
SearchApiFieldTrait::checkHighlighting in src/Plugin/views/field/SearchApiFieldTrait.php
Replaces extracted property values with highlighted field values.

File

src/Plugin/views/field/SearchApiFieldTrait.php, line 978

Class

SearchApiFieldTrait
Provides a trait to use for Search API Views field handlers.

Namespace

Drupal\search_api\Plugin\views\field

Code

protected function combineHighlightedValues(array $extracted_values, array $highlighted_values) {

  // Make sure the arrays have consecutive numeric indices. (Is always the
  // case for $extracted_values.)
  $highlighted_values = array_values($highlighted_values);

  // Pre-sanitize the highlighted values with a very permissive setting to
  // make sure the highlighting HTML won't be escaped later.
  foreach ($highlighted_values as $i => $value) {
    if (!$value instanceof MarkupInterface) {
      $highlighted_values[$i] = $this
        ->sanitizeValue($value, 'xss_admin');
    }
  }
  $extracted_count = count($extracted_values);
  $highlight_count = count($highlighted_values);

  // If there are (at least) as many highlighted values as normal ones, we are
  // done here.
  if ($highlight_count >= $extracted_count) {
    return $highlighted_values;
  }

  // We now compute a "normalized" representation for all (extracted and
  // highlighted) values to be able to find duplicates.
  $normalize = function ($value) {
    $value = (string) $value;
    $value = strip_tags($value);
    $value = html_entity_decode($value);
    return $value;
  };
  $normalized_extracted = array_map($normalize, $extracted_values);
  $normalized_highlighted = array_map($normalize, $highlighted_values);
  $normalized_extracted = array_diff($normalized_extracted, $normalized_highlighted);

  // Make sure that we have no more than $extracted_count values in total.
  while (count($normalized_extracted) + $highlight_count > $extracted_count) {
    array_pop($normalized_extracted);
  }

  // Now combine the two arrays, maintaining the original order by taking a
  // highlighted value only where the extracted value was removed (probably/
  // hopefully by the array_diff()).
  $values = [];
  for ($i = 0; $i < $extracted_count; ++$i) {
    if (isset($normalized_extracted[$i])) {
      $values[] = $extracted_values[$i];
    }
    else {
      $values[] = array_shift($highlighted_values);
    }
  }
  return $values;
}