Entity Field Query and Module

Hi all

Thanks to oddz and some google searches regarding my ongoing Drupal7 dev…
I have created a new block inside a new module eventlist.module which seems to work without any problems.

I just can’t figure out how I display the results to the page from my EFQ.

Hooks for the block

/**
 * Implements hook_block_info()
 */
 function eventlist_block_info() {

  $blocks['eventlist'] = array(
    'info' => t('Custom event block'),
  );

  return $blocks;
}

/**
 * Implements hook_block_view()
 */
function eventlist_block_view($delta = '') {

  $block = array();

  switch ($delta) {
    case 'eventlist':
      $block['subject'] = t('Custom event block');
      $block['content'] = "<h3>Event listing test</h3>";
      break;
  
  }
  return $block;
}

EFQ

/**
 * Create new EFQ
 */
function efq_events() {

$query = new EntityFieldQuery();
  $query
  ->entityCondition('entity_type','node')
  ->entityCondition('bundle','article')
  ->propertyCondition('status', 1)        
  ->propertyOrderBy('created', 'DESC')
  ->range(0,3);
  $result = $query->execute();
  
  $nodes = array();

  if(isset($result['node'])) {
    $ids = array_keys($result['node']);
    $nodes = entity_load('node',$ids);
  }

  $build = array(
    '#prefix'=> '<ul>',
    '#suffix'=> '</ul>',
  );

  foreach($node as $node) {
  
    $build['node_'.$node->nid] = array(
      '#prefix'=> '<li>',
      '#suffix'=> '</li>',
    );
  
    $build['node_'.$node->nid]['title'] = array(
      '#type'=> 'markup',
      '#markup'=> l($node->title,drupal_get_path_alias('node/'.$node->nid)),
      '#prefix'=> '<h3>',
      '#suffix'=> '</h3>',
      '#weight'=> 0,
    );
    
  }
  return $build;
}

Questions

  1. How do I show the results to the page?
  2. How do I even know I have some results?
  3. Do I need to create a new module every time I need a EFQ?
  4. Is what I’m doing above correct and best way?

Thanks, cb

The first thing I would recommend is using a module name that is less likely to conflict with another module. The module name event seems likely to already exist in contrib. Even though you aren’t using that module it is always best to use unique module names. The second is that all functions in a module should typically begin with the module name to prevent conflicts in function names across modules.

With that said I have provided code for a module named eventapp that exposes the event list block.


<?php

/**
 * Implements hook_block_info()
 */
 function eventapp_block_info() {

  $blocks['eventlist'] = array(
    'info' => t('Custom event block'),
  );

  return $blocks;
}

/**
 * Implements hook_block_view()
 */
function eventapp_block_view($delta = '') {

  $block = array();

  switch ($delta) {
    case 'eventlist':
      $block['subject'] = t('Custom event block');
      $block['content'] = eventapp_block_eventlist();
      break;

  }
  return $block;
}

/**
 * Get event list block content.
 */
function eventapp_block_eventlist() {

$query = new EntityFieldQuery();
  $query
  ->entityCondition('entity_type','node')
  ->entityCondition('bundle','article')
  ->propertyCondition('status', 1)
  ->propertyOrderBy('created', 'DESC')
  ->range(0,3);
  $result = $query->execute();

  $nodes = array();

  if(isset($result['node'])) {
    $ids = array_keys($result['node']);
    $nodes = entity_load('node',$ids);
  }

  $build = array(
    '#prefix'=> '<ul>',
    '#suffix'=> '</ul>',
  );

  foreach($node as $node) {

    $build['node_'.$node->nid] = array(
      '#prefix'=> '<li>',
      '#suffix'=> '</li>',
    );

    $build['node_'.$node->nid]['title'] = array(
      '#type'=> 'markup',
      '#markup'=> l($node->title,drupal_get_path_alias('node/'.$node->nid)),
      '#prefix'=> '<h3>',
      '#suffix'=> '</h3>',
    );

  }
  return $build;
}

I was hoping you’d come back oddz
Can’t thank you enough right now been at this for hours :smiley:

Ok, I understand the naming convention issues - I’ll make a note for future reference.
I didn’t change eventlist to eventapp it was slightly confusing me and everything seems to work by just using eventlist.

So what I can gather, we just needed to change the html with the function name so the block called the function, is that right?

$block['content'] = "<h3>Event listing test</h3>";
$block['content'] = eventapp_block_eventlist();

It was also giving an error at first because we had

foreach($node as $node)

instead of

foreach($nodes as $node)

After this little change I got a list of three titles in a list :cool:
Its not the final fix though this is a big stepping stone for me right now using EFQs been reading all about them and trying to learn more PHP, still trying to understand some of the code above (:

Couple of questions

  1. Is this how I’d setup all my future EFQs in place of a view?
  2. What if I didn’t have a block, how else would I show the EFQ result?
  3. What if I have 20 different EFQs, would I need to create 20 different modules?

And finally, in your eyes, this is far much better than creating a view?

Thanks oddz, appreciate your time.