You are here

protected function SearchApiSolrService::extractHighlightingSnippets in Search API Solr 7

Extracts short snippets with highlighting from highlighted field values.

Parameters

string $value: A highlighted field value.

Return value

string[] An array of short, highlighted snippets extracted from the field value.

1 call to SearchApiSolrService::extractHighlightingSnippets()
SearchApiSolrService::getExcerpt in includes/service.inc
Extract and format highlighting information for a specific item from a Solr response.

File

includes/service.inc, line 1565

Class

SearchApiSolrService
Search service class using Solr server.

Code

protected function extractHighlightingSnippets($value) {
  $parts = preg_split('#\\[/?HIGHLIGHT\\]#', $value);
  $num_parts = count($parts);
  if ($num_parts < 3) {
    return array();
  }
  $snippets = array();
  $snippet = '';
  $combined_length = 0;
  foreach ($parts as $i => $part) {

    // Is this a match (even) or context (odd)?
    if ($i % 2 === 1) {
      $snippet .= '[HIGHLIGHT]' . $part . '[/HIGHLIGHT]';
      continue;
    }

    // If there is less than 60 characters between them, we want to fuse two
    // snippets.
    if ($snippet && drupal_strlen($part) < 60) {
      $snippet .= $part;
      continue;
    }

    // Add a suffix context to the existing snippet.
    if ($snippet) {
      $space = strpos($part, ' ', 25);

      // Fall back to just cutting at an arbitrary position, space or no.
      if ($space === FALSE) {
        $space = 30;
      }
      $snippet .= ' ' . substr($part, 0, $space);
      $combined_length += drupal_strlen($snippet);
      $snippets[] = $this
        ->sanitizeAndFormatExcerptSnippet($snippet);
      $snippet = '';

      // Restrict ourselves to three snippets or 300 characters.
      if (count($snippets) >= 3 || $combined_length >= 300) {
        break;
      }
      $part = substr($part, $space);
    }

    // If there are no more matches, stop.
    if ($num_parts <= $i + 1) {
      break;
    }

    // Otherwise, prepare a new prefix for the next match.
    $length = drupal_strlen($part);
    if ($length > 30) {
      $space = strrpos(substr($part, 0, -25), ' ');

      // Fall back to just cutting at an arbitrary position, space or no.
      if ($space === FALSE) {
        $space = $length - 30;
      }
      $part = substr($part, $space + 1);
    }
    $snippet = $part;
  }
  if ($snippet) {
    $snippets[] = $this
      ->sanitizeAndFormatExcerptSnippet($snippet);
  }
  return $snippets;
}