Custom item types / datasource controllers

Last updated on
24 September 2023

Drupal 7 will no longer be supported after January 5, 2025. Learn more and find resources for Drupal 7 sites

Adding new item types allows you to index items that aren't currently supported by the Search API. By default, only entity types (and only those who specify property information) are supported, all others will have to be added by additional modules.

To add a new item type, you'll first need to implement hook_search_api_item_type_info():

/**
 * Implements hook_search_api_item_type_info().
 */
function MODULE_search_api_item_type_info() {
  $types = array();

  $types['MODULE_foo'] = array(
    'name' => t('Example 1'),
    'datasource controller' => 'MODULEDataSourceController',
  );
  $types['MODULE_bar'] = array(
    'name' => t('Example 2'),
    'datasource controller' => 'MODULEDataSourceController',
    'entity_type' => 'node',
  );

  return $types;
}

This example would add the types "Example 1" and "Example 2" as item types to the Search API. You'd then be able to create indexes based on them. The array keys are – as nearly always – just unique identifiers for the types.

The entity_type key allows you to specify types which contain entities. This might be useful when you want to provide a different way of indexing an existing entity type – e.g., as denormalized entities or to index node revisions.

The most important part, though, is the datasource controller. This has to be a class (implementing the SearchApiDataSourceControllerInterface interface) which implements all needed functionality related to an item type – loading items, providing metadata, keeping track of existing items, etc. Several item types can use the same datasource controller – for each item type a separate instance will be created, to which the type is passed. If creating more than one item type, it is usually only a good idea to use a single datasource controller if the item types share enough similarities, though. Otherwise, the code would quickly become unnecessarily confusing.

For creating your own datasource controller, you can use the SearchApiAbstractDataSourceController class as a base. This class already contains sensible defaults for most methods, you'll only need to implement a few methods specific to your item type(s). Please refer to the class documentation for details.

You can also use the SearchApiEntityDataSourceController class as an example. If your item type is no entity, your datasource controller will need to be a bit more complicated, though, as entities are directly supported by the Entity API and therefore don't need to specify their property information (using the getPropertyInfo() method).

External datasources

There is another type of datasource controller for which there is a blueprint contained in the module: external datasources (with the SearchApiExternalDataSourceController). These are datasources for items/item types which you only want to search, but not index. You'll usually also need a custom service class to do this.

Consider the case that you want to include the Drupal.org project search on your site (and have already got the DA's permission). You of course don't want to index all the projects yourself – you would just want the item type available to create an index and then use a custom service class that will pass on any search requests (probably only supporting some subset of the complete Search API query class) to the d.o project search.
The datasource controller would then ignore most of its usual tasks (keeping track of new/changed/deleted items, loading items) and would only need to return some property information, maybe the module title, a bit of metadata (creator, creation date, categories) and a module description teaser (as returned by the project search).
The custom service class would be programmed to parse a Search API query into a Drupal.org project search URL which would return the appropriate results (given no complex conditions are used). The service class would then parse the data of the retrieved results into $results['results'][$id]['fields'] (so the item won't need to be loaded) and return these results. The property information provided by the datasource controller would ensure that the fields can be displayed just like any other search results.

Help improve this page

Page status: No known problems

You can: