Hi all

After working with EntityFieldQuery over the past couple of weeks, I have a few questions if anybody can help.

  1. Do I need to create a new module for every EntityFieldQuery I use, I mean, if I have 20+ EntityFieldQuery does that mean I'll need 20 modules?
  2. When people refer to an Entity do they mean a EntityFieldQuery, what's the difference between the two?
  3. Can I use the same EntityFieldQuery assigned to different hook_block_views?
  4. Is EntityFieldQuery still the preferred choice over Views now that Views are built into the core in Drupal 8?

Thanks, Barry

Comments

Jaypan’s picture

Do I need to create a new module for every EntityFieldQuery I use, I mean, if I have 20+ EntityFieldQuery does that mean I'll need 20 modules?

No. EFQ is simply a method of pulling IDs from the database. You can use this as many times as necessary in a single module.

When people refer to an Entity do they mean a EntityFieldQuery, what's the difference between the two?

An entity type is a Drupal concept that is essentially a data type defined according to the Drupal API. An entity is a single instance of an entity type. For example, Node is an entity type, and when you create a node, that node is an entity. EFQ is a method of querying a bunch of IDs (for nodes, this would be Node IDs - NIDs) by providing a bunch of conditions to define which IDs should be returned.

Can I use the same EntityFieldQuery assigned to different hook_block_views?

Can you give an example of what you mean by this?

Is EntityFieldQuery still the preferred choice over Views now that Views are built into the core in Drupal 8?

I would say Views is already the preferred choice over EFQ by most developers. EFQ is not nearly as widely used as Views is. I don't know if EFQ exists in D8 (I haven't looked), but if it does, I still see Views being the preferred choice.

I likely will not use Views for the most part in D8 myself, as Views is essentially a GUI for SQL queries, and I can write my own SQL queries without the overhead of Views. But then again I thought I wouldn't use fields when moving from D6 to D7, and now I use fields for everything, so only time will tell.

computerbarry’s picture

Thanks Jaypan

No. EFQ is simply a method of pulling IDs from the database. You can use this as many times as necessary in a single module.

Do you mean the same EFQ or multiple EFQs in the same module, doesn't every EFQ have a different query condition? Things would get confusing and uncategorised if we had multiple EFQs in the same module. I mean for example, we have a EFQ for events, EFQ for photos which query for different nodes/ids, don't you think it would be better to create a separate module for each query/condition? Or would it be better to have a sort of template.php which hold all our functions but instead create template.module for all EFQs. I'm also wondering if there is a big performance benefit if we keep everything in 1 module. Or at least keep 4 or 5 related EFQs per module?

For example, Node is an entity type, and when you create a node, that node is an entity.

That sort of makes sense. So its basically just another word for Node, just in a EFQ context, correct?

Can you give an example of what you mean by this?

Sure, this kind of relates to the first question. Take for example the EFQ we worked on last week, I need to use this EFQ on the Frontpage and the What's on page inside different blocks. The only thing thats different is the date format and the range. So instead of writing a new EFQ with nearly identical code, I just reference it for another block.

I've already tried this and it seems to work, though is this correct? Surely if it saves me writing another EFQ, I simply added a couple of $variables in the EFQ, thats what (2, "l, j F") and (6 "F") are for below. So in theory, I could have 20+instances of the same EFQ?

function eventlist_block_view($delta = '') {
  $block = array();

  switch ($delta) {
    case 'eventlist':
      $block['subject'] = t('Custom event block');
      $block['content'] = fulleventlist_block_eventlist(2, "l, j F");
      break;
    case 'fulleventlist':
      $block['subject'] = t('Full event listing block');
      $block['content'] = fulleventlist_block_eventlist(6, "F");
      break;
  }
  return $block;
}
I would say Views is already the preferred choice over EFQ by most developers. EFQ is not nearly as widely used as Views is.

Yes I agree, I've worked with a few guys in the past and Views seems to be all the craze. A lot of people aren't even aware of EFQs, though personally, once you start to understand things EFQs are the way forward for me. More control and less files to override if you want to make changes to markup etc. It sort of feels wrong to me now if I use a view :)

I don't know if EFQ exists in D8

Yes its still there just a slight change to some code, small example below, had a look last night - drupal.org/node/1827278

d7- new EntityFieldQuery();
d8 - \Drupal::entityQuery();

Views is essentially a GUI for SQL queries, and I can write my own SQL queries without the overhead of Views

But why do you prefer writing your own SQL if EFQ can do it? Personally preference? Performance benefits?
Are you saying you never use Views anymore?

Hope this all makes sense,
Cheers, Barry

The more you learn.... the more you learn there is more to learn.

Jaypan’s picture

Do you mean the same EFQ or multiple EFQs in the same module

Either/or. You could potentially have more than one EFQ in the same function, depending on what you are doing/building.

Things would get confusing and uncategorised if we had multiple EFQs in the same module. I mean for example, we have a EFQ for events, EFQ for photos which query for different nodes/ids, don't you think it would be better to create a separate module for each query/condition?

The more modules you have, the slower your site will become. Each page requires aggregating every .module file for every enabled module on the site. The more files you aggregate, the longer the page load. So the more modules you have, the longer the page load.

Or would it be better to have a sort of template.php which hold all our functions but instead create template.module for all EFQs.

a .module file is the same as a template.php file. It's a file that holds functions.

Jaypan’s picture

I've already tried this and it seems to work, though is this correct?

Yes, that's exactly how I do it. Create a function that returns your values. Use the function wherever necessary.

But why do you prefer writing your own SQL if EFQ can do it? Personally preference? Performance benefits?

There are two issues with EFQ for me:
1) EFQ requires loading up the whole EFQ class, along with all the overhead that goes with it.
2) EFQ has its limits, limits I don't run into when I use db_query() or db_select(). For example, I believe EFQ can only work with AND conditions, not OR conditions (though it's been a while since I used it, so I could be wrong). Also, sometimes I will be making some particularly complicated queries that EFQ can't handle. For example, I recently had to pull all the records that didn't exist in a given table based on a join of about 4 other tables. EFQ couldn't have handled this, my own query could. I don't think views could have handled it either for that matter.

Are you saying you never use Views anymore?

I never really did, in D5, D6 or D7. Over the years, I've tried going back to it a few times, and used it on sites, but I almost always end up running into some limitation that I spend a day trying to figure out, then give up and go back to my own custom query. The only thing I really use Views for anymore is Calendars, and one of these days I'm intending to dig down into the Calendar module to see if I can't bypass Views for that even, as I've run into some major stumbling blocks with the calendar module in the past, as a result of views limitations.

computerbarry’s picture

Either/or. You could potentially have more than one EFQ in the same function, depending on what you are doing/building

Advanced stuff. Don't think I'm quite at that level yet though hopefully very soon. Does this involve using the EFQ extend?
I've added a small OOP snippet below to my template.php which I'm using, learning how to reduce code, add variables etc.
Do you write this sort of stuff? Use this approach?

/** Quick EFQ node setup.*/
class NodeFieldQuery extends EntityFieldQuery {
  function __construct($node_type, $order_by, $status = 1) {
    $this->entityCondition('entity_type', 'node')
         ->entityCondition('bundle', $node_type)
         ->fieldOrderBy($order_by, 'value', 'ASC')
         ->propertyCondition('status', $status);
  } 
}
The more modules you have, the slower your site will become. Each page requires aggregating every .module file for every enabled module on the site...

I was kind of aware of this though didn't realise it meant EFQs. Though after all, its a module where creating. Good to know and definitely keep this in mind. Drupal also has a lot of modules active out of the box, I've also added a few modules myself, is there a way or something that detects what modules aren't being used so you can deactivate them? As you say, reduce the aggregating for every page? Boost the speed.

a .module file is the same as a template.php file. It's a file that holds functions.

Does the template.php still need to get aggregating for every page like the module file does?

Yes, that's exactly how I do it. Create a function that returns your values. Use the function wherever necessary.

Cool, so I am learning something, right on!

EFQ requires loading up the whole EFQ class, along with all the overhead that goes with it.

Yes I see, though faster than views :)

EFQ has its limits, limits I don't run into when I use db_query() or db_select()...

I look forward to when my EFQs can't handle my complex queries ha. Some good info here thanks. Which brings me to… you mention you like to use db_query() or db_select(), where exactly does all this logic go? Can you place everything inside a block, or do you create a module for your query/sql statements like we do for EFQ, maybe the template.php as mentioned earlier? Or does it even matter where it goes? I've wrote some sql and queried my DB many times in the past for more static sites and usually just placed it at the top of my page, or in an include file, does this sort of work the same way?

I almost always end up running into some limitation that I spend a day trying to figure out, then give up and go back to my own custom query.

I feel the pain :) I think once you understand and can write your own queries with speed it becomes a no brainer than spending all day setting up views. Though, as you say lots of people still use Views with passion and quite happy with how things work.

Cheers, Barry

The more you learn.... the more you learn there is more to learn.

WorldFallz’s picture

it becomes a no brainer than spending all day setting up views.

afaik, this is the only thing jay and i disagree on, lol.

Views definitely has a learning curve-- much like drupal itself. Your statement above is very often a meme repeatedly used about drupal itself ("easier to write my own CMS with <insert framework of the day name here> than spend months learning drupal"). Yes it takes some initial up front investment to learn it, but once you've spent that time, the future time savings can be brilliantly significant.

I can write my own queries as well, and usually did in d5 (views was just a babe in the woods then). But now I use it extensively and the time it saves me writing code to create page callbacks, filters, charts, slideshows, you name it -- is unquantifiable. Not to mention the added benefit of allowing certain privileged users who are not coders the ability to modify their views themselves. And views_content_cache.

When someone walks over to my desk and tells me they need "a 'report' to show # of x grouped by y both with a listing and a pie chart" -- I can literally have it up and running at a url with permissions before they make it back to their desk.

And it's very true that views can't handle everything-- but with views_query_alter and views_raw_sql I find very little I have to completely hand code (mostly complex charts or missing record type stuff). And there will always be times when something is very performance sensitive and would benefit from a hand crafted query. But for many routine tasks I find it to be a life saver.

imo the biggest drawback to relying on views was the lag between a major version core upgrade and the compatible views release. With views in core for d8 that goes away. Moreover, though you can leave it disabled, with many sites having it enabled to power the admin screens (core customizable admin screens are worth their weight in gold!), it will often be enabled already anyway.

Jaypan’s picture

afaik, this is the only thing jay and i disagree on, lol.

I don't even think we disagree. I think Views is a great module, if it wasn't, it wouldn't be used in the massive numbers it is, and it wouldn't have been added as part of core for D8. I just find writing a DB query, combined with the usage of view modes, works better for me.

computerbarry’s picture

Nice to see other peoples views and thoughts on things, cheers.

I can literally have it up and running at a url with permissions before they make it back to their desk.

Lol I don't believe that, must be a big office WorldFallz :) Though I can see where you're coming from.

Views definitely has a learning curve-- much like drupal itself

I agree, though I'd say learning PHP and writing your own query's has a much bigger learning curve than setting up a View using the GUI.

Like most things, it comes down to personally preference and what you most comfortable with. When I first used a View I was overwhelmed with the power and what I could create in such little time without writing any code. It sort of felt wrong because it was so easy. Though when I needed to amend the markup, I needed to create and override 3-4 files to get the output I needed, basic lists without classes, rich snippet data, adding unique wrappers and other types of attributes. It was fairly straight forward once I figure out the process. I'd say Views is great and I do like it though after stumbling across EFQs, for me right now, I think EFQs are better. One simple snippet and you have everything in $result.

I only have a limited amount of Drupal experience so far, even PHP for that matter, but knowing how to use and setup Views is a must with most companies, jobs I've seen, even jobs I've worked on require you to know about Views - If you use Drupal, you should know how to use Views. I've spoken about this on other forums and what keeps popping up is speed and performance. EFQs are faster than Views, Drupal 7 anyway.

avoiding views will provide a much more stable architecture

writing queries instead of views is going to be faster and more stable

I suppose it comes down to who you're doing the work for, budgets, size of projects, timescales etc. In a nutshell, a suppose its nice to know both so you can use the best tools for the job :)

Thanks, Barry

Jaypan
Did you manage to have a look at our earlier post regarding EFQ questions, thanks.

The more you learn.... the more you learn there is more to learn.

WorldFallz’s picture

It is a large floor, lol, but i promise in all honesty I do that type of report so often it literally takes me 5 minutes. ;-)

computerbarry’s picture

It is a large floor, lol, but i promise in all honesty I do that type of report so often it literally takes me 5 minutes. ;-)

Lol nice to see you have a sense of humor :)
Though I understand exactly what you mean WorldFallz, once you do things on a regular basis just becomes second nature, cool.

Just a final question here taken from above.

Jaypan mentions using db_query() or db_select(), where exactly does all this logic go? Can you place everything inside a block, or do you create a module for your query/sql statements like we do for EFQ, maybe the template.php as mentioned earlier? Or does it even matter where it goes? I've wrote some sql and queried my DB many times in the past for more static sites and usually just placed it at the top of my page, or in an include file, does this sort of work the same way?

Thanks, Barry

The more you learn.... the more you learn there is more to learn.

Jaypan’s picture

I'll do something like this to create a page:

function mymodule_menu()
{
  $menu['path/to/page/%'] = array
  (
    'title' => 'some title',
    'page callback' => 'my_page_callback',
    'page arguments' => array(3),
    'access callback' => TRUE,
  );
  return $menu;
}

function my_page_callback($some_id)
{
  $results = db_query('SELECT id FROM {some_table} WHERE some_id = :some_id', array(':some_id' => $some_id))->fetchAllAssoc('id');
  $ids = array_keys($results);
  $entities = load_some_entity_multiple($ids);
  $renderable = array();
  foreach($entities as $entity)
  {
    $renderable[] = view_some_entity($entity, 'some_view_mode');
  }
  $page = array
  (
    'some_entity_list' => array
    (
      '#prefix' => '<div id="some_entity_listing_page">',
      '#suffix' => '</div>',
      'entities' => $renderable,
    ),
  );
  drupal_alter('my_page_callback', $page);
  return $page;
}

This is the general manner in which I build a page.
1) Use a db_query() to get the IDs I need
2) Use those IDs to load some entities
3) Set the entities to be viewed using some view mode
4) Build a render array for the page
5) Allow that render array to be altered (so that JS and CSS can be added in the theme if necessary)
6) Return the render array

WorldFallz’s picture

Although I have occasionally (cough-cough) resorted to code in a custom block, in general, best practice is to put all code into modules or themes. Template files should only contain minimal logic type php (if-then-else) related strictly to presentation. More complex logic can be added to the template.php file or in module files.

I always add a custom.module module to very site for bits and pieces of code (custom blocks, handy functions, form_alters, views_query_alters, preprocess functions that don't belong in the theme, etc). Then, depending on whether or not significant chunks of functionality are required, I might spin off other custom modules for site specific things that don't really make sense as a drupal.org contrib (when i do end up creating something that might benefit others, I contribute it to drupal.org).

computerbarry’s picture

best practice is to put all code into modules or themes

When you mention themes, do you mean inside your sub-theme directory so its just for that site?

Template files should only contain minimal logic type php (if-then-else) related strictly to presentation

You say template files, are you referring to the .tpl.php files?

I always add a custom.module module to very site for bits and pieces of code (custom blocks, handy functions, form_alters, views_query_alters, preprocess functions that don't belong in the theme, etc).

Sort of a function/code library you can build and use again and again on different projects?

Thanks, Barry

Jaypan
I have a few questions about the new pages, I'll create a new thread shortly to reduce confusion.

The more you learn.... the more you learn there is more to learn.

WorldFallz’s picture

When you mention themes, do you mean inside your sub-theme directory so its just for that site?

It may or may not be a subtheme, but I was referring to the type of stuff you do with preprocess functions in a template.php file. However, the main point is, code should be in the file system (for drupal that means modules and themes), not in fields using the php module/filter.

You say template files, are you referring to the .tpl.php files?

yep.

Sort of a function/code library you can build and use again and again on different projects?

Not usually. My projects/sites/apps are so different, there's very little overlap like that. Again, the main point is you need some place to put code for a site that is not entered through the UI.

computerbarry’s picture

Thanks WorldFallz
Making a bit more sense now, just wanted to double check things and make sure I'm on the same page.

So much stuff to learn and understand ha, though like you say, steep learning curve... but worth it in the end :)

Well, I'll bring this thread to a close and thanks again for all your help and guidance, including Jaypan, thank you.

Barry

The more you learn.... the more you learn there is more to learn.

WorldFallz’s picture

no problem-- happy to help ;-)