2

I am having an interesting problem with paging the results of a query. The pager is visible to all users except those who are assigned the built-in 'administrator' role. I have tried the code on two separate Drupal installs and the result is the same: the administrator cannot see the pager. The markup is not visible in the page source.

I have tried my solution using both EntityFieldQuery and db_select, but the problem persists. Here is the code for the EntityFieldQuery version:

function build_area_table() {
  $header = array(
    'area_name' => array(
      'data' => 'Area',
      'type' => 'property',
      'specifier' => 'title',
      'sort' => 'asc',
    ),
    'level_range' => array(
      'data' => 'Level range',
      'type' => 'field',
      'specifier' => array('field' => 'field_area_level_range', 'column' => 'value'),
      'sort' => 'desc',
    ),
  );

  $query = new EntityFieldQuery();
  $query = $query->pager(5); # I have more than 5 rows being returned
  $query = $query->entityCondition('entity_type', 'node')
    ->propertyCondition('type', 'area')
    ->propertyCondition('status', 1)
    ->tableSort($header);

  $result = $query->execute();

  $nodes = null;
  // $result['node'] contains a list of nids where the title matches
  if (!empty($result['node'])) {
    // You could use node_load_multiple() instead of entity_load() for nodes
    $nodes = node_load_multiple(array_keys($result['node']));
  }

  // do something to output your results here.
  $td = array();
  foreach ($nodes as $area) {
    $td[] = array(
      'area_name' => array(
        'data' => l($area->title, 'node/'. $area->nid),
        'class' => array('area-name'),
        ),
        'level_range' => array(
          'data' => $area->field_area_level_range['und'][0]['safe_value'],
          'class' => array('level-range'),
        ),
    );
  }

  $areaTable = array(
    'area-table' => array(
      '#theme' => 'table',
      '#header' => $header,
      '#rows' => $td,
      '#empty' => 'No areas to display.',
    ),
    'area-pager' => array(
      '#markup' => theme('pager')
    ),
  );

  return $areaTable;
}

The table is rendered using Drupal 'render' in the template page. Does anyone have any ideas as to what the problem may be? I have read some posts regarding changing the pager ID, but any changes I make do not seem to have any effect.

EDIT: I am not using the Views module, which seems cause a conflict with pagers as reported by many other people.

Thanks!

1 Answer 1

4

Looks like I found the answer. It appears easier (and more efficient) to use the db_select instead, at least for the number of fields I am sorting on. As suspected it was the pager colliding with another pager on the page, although I am not sure what pager this could be. The pager seems to working fine for all users now that I added '->element(0)' to the db_select. Here is some code:

function build_area_table() {
  $header = array(
    'area_name' => array(
      'data' => 'Area',
      'field' => 'n.title',
      'sort' => 'asc',
    ),
    'level_range' => array(
      'data' => 'Level range',
      'field' => 'flr.field_area_level_range_value',
      'sort' => 'asc',
    ),
  );

  $query = db_select('node', 'n')
            ->extend('PagerDefault')->element(0) # fix displaying pager for all users
            ->extend('TableSort');
  $query->join('field_data_field_area_level_range', 'flr', 'n.nid = flr.entity_id');
  $result = $query
    ->fields('n', array('nid', 'title'))
    ->fields('flr', array('field_area_level_range_value'))
    ->condition('type', 'area')
    ->limit(2)
    ->orderByHeader($header)
    ->execute();

  # build the table
  $td = array();
  foreach ($result as $area) {
    $td[] = array(
      'area_name' => array(
        'data' => l($area->title, 'node/'. $area->nid),
        'class' => array('area-name'),
        ),
        'level_range' => array(
          'data' => format_area_level_range($area->field_area_level_range_value),
          'class' => array('level-range'),
        ),
    );
  }    

  $areaTable = array(
    'area-pager' => array(
      '#markup' => theme('pager')
    ),
    'area-table' => array(
      '#theme' => 'table',
      '#header' => $header,
      '#rows' => $td,
      '#empty' => 'No areas to display.',
    ),
  );

  return $areaTable;
}

I could probably achieve the same using EFQ, although I can't find an EFQ version of '->element()'. I tried specifying the element via theme like so:

theme('pager', array('element' => 0))

but there would need to be some kind of check based on the user role, as 0 works for administrators but not for other roles and vice versa. Hopefully this can save someone else some time as well!

1
  • The EFQ version of '->element()' is the second argument in '$query->pager($limit, $element)'. Also, note that 'element' is the number of the pager and has nothing to do with the user. I suggest you try a large number like 999 so that it doesn't collide with other pagers in your views for example. Not an optimal solution but works. Thanks for your code. Cheers.
    – Mario Awad
    Commented May 10, 2014 at 13:25

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.