Checking out EntityFieldQuery

One of the challenges of relying on entities and fields for the core components of your modules is that the data for any given object will be spread across any number of tables. For example, a product line item on an order in Drupal Commerce has data in the commerce_line_item table, two price field tables (unit / total price), and one product reference field table. Querying this data directly is quite cumbersome, especially when you throw languages and revisions into the mix.

Enter EntityFieldQuery. This piece of hotness tucked into Drupal 7's entity.inc lets you query data objects based on their entity type, bundle, entity properties, field values, and more. When executed it can return the actual objects themselves or a count of how many it found. It's a piece of genius that has already saved us once in the development of Drupal Commerce.

The most recent example lies in the Product Reference module. This is the module that actually defines the product line item type, because it uses a product reference field to relate the line item on the order to the actual product it represents. If a line item exists referencing a particular product, the product should not be able to be deleted (although a product can be disabled if it should no longer be available for sale). A simple EntityFieldQuery was able to determine if there are any matching products that should prevent a product from being deleted:

<?php
/**
 * Implements hook_commerce_product_can_delete().
 */
function commerce_product_reference_commerce_product_can_delete($product) {
 
// Use EntityFieldQuery to look for line items referencing this product and do
  // not allow the delete to occur if one exists.
 
$query = new EntityFieldQuery();

 
$query
   
->entityCondition('entity_type', 'commerce_line_item', '=')
    ->
entityCondition('bundle', 'product', '=')
    ->
fieldCondition('product', 'product_id', $product->product_id, '=')
    ->
count();

  return
$query->execute() > 0 ? FALSE : TRUE;
}
?>

Pretty sweet, eh? I think so. My compliments and exceeding gratitude to the folks who worked hard to make sure this made it into Drupal 7. From what I understand, it wasn't always a given, but this really opens the door even further for modules to fully embrace fieldable entities as the standard for their complex data objects.

Ryan's picture
President / CEO
Posted December 1, 2010

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <p> <br>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.