I have a use case where the content author would like to search for an entity through the entity reference autocomplete widget but not by the title field. They would like to search for results by another field on the entity. It would be very nice to not have to completely override the autocomplete callback function but instead have an alter at the end of the autocomplete request that allows other modules to add their matches


function entityreference_autocomplete_callback_get_matches($type, $field, $instance, $entity_type, $entity_id = '', $string = '') {
  $matches = array();

  $entity = NULL;
  if ($entity_id !== 'NULL') {
    $entity = entity_load_single($entity_type, $entity_id);
    if (!$entity || !entity_access('view', $entity_type, $entity)) {
      return MENU_ACCESS_DENIED;

  $handler = entityreference_get_selection_handler($field, $instance, $entity_type, $entity);

  if ($type == 'tags') {
    // The user enters a comma-separated list of tags. We only autocomplete the last tag.
    $tags_typed = drupal_explode_tags($string);
    $tag_last = drupal_strtolower(array_pop($tags_typed));
    if (!empty($tag_last)) {
      $prefix = count($tags_typed) ? implode(', ', $tags_typed) . ', ' : '';
  else {
    // The user enters a single tag.
    $prefix = '';
    $tag_last = $string;

  if (isset($tag_last)) {
    // Get an array of matching entities.
    $entity_labels = $handler->getReferencableEntities($tag_last, $instance['widget']['settings']['match_operator'], 10);

    // Loop through the products and convert them into autocomplete output.
    foreach ($entity_labels as $values) {
      foreach ($values as $entity_id => $label) {
        $key = "$label ($entity_id)";
        // Strip things like starting/trailing white spaces, line breaks and tags.
        $key = preg_replace('/\s\s+/', ' ', str_replace("\n", '', trim(decode_entities(strip_tags($key)))));
        // Names containing commas or quotes must be wrapped in quotes.
        if (strpos($key, ',') !== FALSE || strpos($key, '"') !== FALSE) {
          $key = '"' . str_replace('"', '""', $key) . '"';
        $matches[$prefix . $key] = '<div class="reference-autocomplete">' . $label . '</div>';

  // implment a hook to futz with autocomplete results so that other modules may add their results or alter these ones :)
  foreach (module_implements('entityreference_alter_matches') as $module) {
    $function = $module . '_entityreference_alter_matches';
    $function($matches, $field, $instance, $entity_type, $entity_id, $string);


#3 1863944-alter_autocomplete_callback-3.patch473 bytesguillaumev
PASSED: [[SimpleTest]]: [MySQL] 121 pass(es).
[ View ]


rudiedirkx’s picture

I'd like this too, but of course using drupal_alter():

$context = compact('type', 'field', 'instance', 'entity_type', 'entity');
drupal_alter('entityreference_matches', $matches, $context);
mcpuddin’s picture

This would be very nice to have. The only other option I found is this roundabout way of altering the callback.

guillaumev’s picture

Status:Active» Needs review
new473 bytes
PASSED: [[SimpleTest]]: [MySQL] 121 pass(es).
[ View ]

I also need this, to alter the output of the results. Here is a patch that adds the alter hook from #1

rudiedirkx’s picture

Status:Needs review» Reviewed & tested by the community


@mcpuddin That's smart. Did you copy all logic or use the normal function and json_decode() its result?

DamienMcKenna’s picture