You are here

public function SearchApiAlgoliaService::indexItems in Search API Algolia 7

Implements indexItems.

Naming convention:

  • items

    • item

      • property

        • type
        • entity_type
        • value : single value or array.

Overrides SearchApiServiceInterface::indexItems

File

includes/service.inc, line 124
Contains SearchApiAlgoliaService.

Class

SearchApiAlgoliaService
SearchApiAlgoliaService class.

Code

public function indexItems(SearchApiIndex $index, array $items) {
  $items_to_index = array();
  $items_indexed = array();

  // Retrieving the entity key ('nid' for nodes, 'uid' for users, etc...).
  $entity_key = entity_get_info($index->item_type)['entity keys']['id'];

  // Connect to the Algolia service.
  $this
    ->connect($index);

  // Iterate over all the items ready for indexing.
  foreach ($items as $item) {
    $item_to_index = array();

    // And then iterate over all the properties of these items.
    foreach ($item as $key => $property) {

      // Do not index the property if its value is not set.
      if (isset($property['value'])) {

        // Do not process the entity id at that stage. Its value is indexed
        // separately as it requires a special property name (ObjectID) in
        // order to be indexed by Algolia.
        if ($key != $entity_key) {

          // If the property type is defined as a list and entity_type is set,
          // we are facing a multivalued entity (checking list<integeger> is
          // not enough as this could be used by a standard select, with no
          // reference).
          // @todo Handle multivalued fields which are not entity reference.
          if (preg_match('/^list<[^>]+>/', $property['type']) && isset($property['entity_type'])) {
            $entity_type = $property['entity_type'];
            foreach ($property['value'] as $property_list_value) {
              $wrapper = entity_metadata_wrapper($entity_type, entity_load_single($entity_type, $property_list_value));
              $item_to_index[$key][] = $wrapper
                ->label();
            }
          }
          else {

            // If entity_type is defined, it means we are facing an entity
            // reference. We then use an entity wrapper to output it.
            if (isset($property['entity_type'])) {
              $entity_type = $property['entity_type'];
              $wrapper = entity_metadata_wrapper($entity_type, entity_load_single($entity_type, $property['value']));
              $property_value = $wrapper
                ->label();
            }
            else {
              if ($property['type'] == 'integer') {

                // We need to transtype the content of integer fields (as they
                // are stored as string) so that Algolia sees them as
                // integers.
                // @todo MAYBE: if more types need to be recognized, make
                // something more scalable here.
                $property_value = (int) $property['value'];
              }
              else {
                $property_value = $property['value'];
              }
            }
            $item_to_index[$key] = $property_value;
          }
        }
        else {

          // Match the entity key to the objectID primary key required by
          // Algolia.
          $item_to_index['objectID'] = $item[$entity_key]['value'];
        }
      }
    }

    // Add the properly formatted items to the batch.
    $items_to_index[] = $item_to_index;
  }
  try {

    // Once a batch is ready, send them over to Algolia.
    $items_indexed = $this
      ->getAlgoliaIndex()
      ->saveObjects($items_to_index);
  } catch (Exception $e) {
    throw new SearchApiException($e
      ->getMessage());
  }

  // Returns an array of properly indexed objectIDs for Search API's
  // statistics. Depending on the type of entity being indexed, this can be
  // an array of 'nids', 'uids', 'tids', etc...
  return $items_indexed['objectIDs'];
}