4

I need to use the OR operator on an EntityFieldQuery which I understand can only be accomplished via addTag and hook_query_TAG_alter.

My query at present:

$query = new EntityFieldQuery();
$query->propertyOrderBy('created', 'DESC');
$query->entityCondition('entity_type', 'node')
    ->entityCondition('bundle', 'news')
    ->propertyCondition('status', 1)
    ->fieldCondition('field_pub_year', 'value', $year, '=');
if(isset($_GET['country_id'])){
    $country = $_GET['country_id'];
    $query->fieldCondition('field_related_country', 'target_id', $country, '=');
}
if(isset($keywords)){
    $query->addTag('search');
}
$result = $query->execute();

Without much more than a rudimentary knowledge of Drupal, I would expect that the following function, inserted into my template, might work:

function hook_query_search_alter(QueryAlterableInterface $query){
    $or = db_or()
      ->fieldCondition('title', 'value','%'. $keywords .'%', 'LIKE')
      ->fieldCondition('body', 'value','%'. $keywords .'%', 'LIKE');
    $query->condition($or);
}

Yet, it seems to do nothing...

I'm having equal luck googling this problem. Appreciate any suggestions. Thanks.

Update:

I moved the alter function into a module and re-wrote it to look like:

function modulename_query_search_alter(QueryAlterableInterface $query){
    $terms = $query->getMetaData('terms');
    $words = "%".$terms."%";
    $or = db_or()->condition('body', $words, 'LIKE')->condition('title', $words, 'LIKE');
    $query->condition($or);
}

but I now get an unknown column body error. Removing that condition works correctly and results are filtered by title field. Not sure what the deal is with that...

2 Answers 2

6

Solution to using 'OR' queries with EntityFieldQuery:

The query, note the addTag() and addMetaData():

$query = new EntityFieldQuery();
$query->propertyOrderBy('created', 'DESC');
$query->entityCondition('entity_type', 'node')
    ->entityCondition('bundle', 'news')
    ->propertyCondition('status', 1);
if(isset($keywords)){
    $query->addTag('search');
    $query->addMetaData('terms', $keywords);
}
$result = $query->execute();
if(isset($result['node'])){
    $nids = array_keys($result['node']);
} else {
    $nids = array();
}
$news = node_load_multiple($nids);

Then, within a module or something, the hook_query_TAG_alter looks like:

function MODULENAME_query_TAGNAME_alter(QueryAlterableInterface $query){
    $terms = $query->getMetaData('terms');
    $words = "%".$terms."%";
    $query->leftJoin('field_data_field_subtitle', 's', 'node.nid = s.entity_id');
    $or = db_or()->condition('s.field_subtitle_value', $words, 'LIKE')->condition('title', $words, 'LIKE');
    $query->leftJoin('field_data_body', 'b', 'node.nid = b.entity_id');
    $or->condition('b.body_value', $words, 'LIKE');
    $query->condition($or);
}

Above example shows how to join custom field tables and query them using 'OR' along with title and body fields.

0

You want hook_entity_query_alter, your function signature is broken.

Also it's considered bad practice to use $_GET directly.

1
  • ..but I only want to alter the query when a particular tag is present.
    – aperture
    Oct 24, 2014 at 18:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.