What and Why EntityFieldQuery?
What and Why EntityFieldQuery?
Most of the time when we want to display data in Drupal we use Views. However, Views can messed with and even the most trained end user, as we all know, can and will break things. Using EntityFieldQuery (EFQ) allows us to do the same thing that Views does, but without a GUI, so there will be no way for our ambitious end user to break the display. The best part of all of this is that it is core; no need for any extra modules.
The purpose of this blog is to go over how to extract data using Drupal's EntityFieldQuery API.
What is EntityFieldQuery:
You can read up on the official docs of EFQ here, but at the end of the day EFQ is nothing more than a class that allows us to extract data from Drupal’s database abstraction layer. But the best part is you can do all of this with very little knowledge of any SQL.
Creating a basic query:
Every query begins by initializing an instance of the EFQ class like this:
$query = new EntityFieldQuery();
Super simple right? Now that we have our query, lets add some conditions and extract some entities. For this example we want to get all our article nodes, that are published, and have a specific taxonomy term reference on a field called tags.
$query->entityCondtion('entity_type', 'node')
->entityCondition('bundle', 'article')
->propertyCondition('status', NODE_PUBLISHED)
->fieldCondition('field_tags', 'tid', 1, '=')
->fieldOrderBy('field_tags';
At this point we've set up, esentially our database query we would like to make. So now lets actually get our data and store it's results in a variable. This is simply done by calling the execute method like so.
$results = $query->execute();
if(isset($results['node'])) {
// We found nodes!
}
The $results variable is populated with an associative array with the key being the entity type; So in our case $results['node']. Note the $result won't have the 'node' key when it's empty so this is why we are checking if isset
So let’s look at what our query says:
First, we are specifying the type of entities we want with "entity_type", in this case we want node entities.
$query->entityCondtion('entity_type', 'node')
Next, we are further specifying our query by saying we want nodes, but only the nodes that are in the bundle of "article"
->entityCondition('bundle', 'article')
Note: for the second argument it can be a string or an array like below, however, when using an array you must use the operator parameter of 'IN' or 'NOT IN':
->entityCondition('bundle', array('article', 'page'), 'IN');
In the 3rd line we are specifying we want only published nodes (you may also use NODE_NOT_PUBLISHED or 0 for unpublished, and 1 for published as well).
->propertyCondition('status', NODE_PUBLISHED)
and lastly we are specifying that we want to get only nodes that have a reference to a taxonomy term with tid of 1.
->fieldCondition('field_tags', 'tid', 1, '=');
Note: here we could say we want all published article nodes that are published, but don't have a reference to a specific id by changing the operator.
->fieldCondition('field_tags', 'tid', 1, '!=');
Or if we wanted all published article nodes that contain a tid of multiple terms we'd do something like this:
->fieldCondition('field_tags', 'tid', array(1, 14), 'IN');
Property Condition Vs. Field Condition:
Properties are specific to that entity type and are mapped to columns in the database table where the entity itself is stored. If you are able to view your database structure, you can see this on the node table. (Insert Image of describe).
->propertyCondition('status', NODE_PUBLISHED)
So title, nid, language, created, uid, status, etc are all properties on that specific entity type.
A field condition, as it sounds, is a field on the entity meeting specific criteria. The first parameter is the machine name of the field you would like to filter on. In our case it’s called 'field_tags'. The second parameter is 'column'. Now this can be confusing to new comers who don’t understand how Drupal’s Field API works.
In short, because of Field API, each field you create gets it’s own table in the database, however, the table is prefixed with 'field_data'. So we can see in our database we have a table called 'field_data_field_tags'. For our tags field the database column we want to use ‘field_tags_tid', however, we don't use the field name prefix so 'tid' is the actual argument we would use.
In conclusion
EntityFieldQuery is a great tool that allows developers the ability to quickly, and efficiently, extract data from the database without ever writing out a single line of SQL. Stay tuned for the next post where we will go over a few more things that you can do to your query to further suit your needs and how to take our results from EntityFieldQuery and display them on it's own page.
Want to talk about how we can work together?
Ryan can help