You are here

function flippy_build_list in Flippy 7

Function that builds the list of nodes

3 calls to flippy_build_list()
flippy_node_view in ./flippy.module
Implements hook_node_view().
flippy_pager_block in ./flippy.module
Render the Flippy pager block.
_flippy_add_head_elements in ./flippy.module
Add the previous/next elements to the page head, if enable for the content type of the given node.

File

./flippy.module, line 309
Allows administrators to add previous/next pagers to any node type.

Code

function flippy_build_list($node) {
  $master_list =& drupal_static(__FUNCTION__);
  if (!isset($master_list)) {
    $master_list = array();
  }
  if (!isset($master_list[$node->nid])) {

    // Check to see if we need custom sorting
    if (variable_get('flippy_custom_sorting_' . $node->type, FALSE)) {

      // Get order
      $order = variable_get('flippy_order_' . $node->type, 'ASC');

      // Get sort
      $sort = variable_get('flippy_sort_' . $node->type, 'created');
    }
    else {
      $order = 'ASC';
      $sort = 'created';
    }

    // Validate that the sort criteria is OK to use
    $base_table_properties = array_keys(_flippy_sorting_properties());
    $field_value = NULL;

    // If the sort criteria is not in the base_table_properties array,
    // we assume it's a field
    if (!in_array($sort, $base_table_properties)) {

      // get the value of the current node's field (use the first one only)
      $current_field_items = field_get_items('node', $node, $sort);
      if (!isset($current_field_items[0]['value'])) {

        // should never happen, but just in case, fall back to post date ascending
        $sort = 'created';
        $order = 'ASC';
      }
      else {

        // Otherwise save the field value for later
        $field_value = $current_field_items[0]['value'];
      }
    }

    // Depending on order, decide what before and after means
    $before = $order == 'ASC' ? '<' : '>';
    $after = $order == 'ASC' ? '>' : '<';

    // Also decide what up and down means
    $up = $order == 'ASC' ? 'ASC' : 'DESC';
    $down = $order == 'ASC' ? 'DESC' : 'ASC';

    // Create a starting-point EntityFieldQuery object
    global $language;
    $query = db_select('node', 'n');
    $query
      ->condition('n.type', $node->type)
      ->condition('n.status', 1)
      ->condition('n.nid', $node->nid, '!=')
      ->condition(db_or()
      ->condition('n.language', array(
      $language->language,
      LANGUAGE_NONE,
    ), 'IN')
      ->condition('n.language', $node->language, '='))
      ->fields('n', array(
      'nid',
      'title',
    ))
      ->range(0, 1)
      ->addTag('node_access')
      ->addTag('alter_flippy_query');

    // Create the individual queries
    $first = clone $query;
    $prev = clone $query;
    $next = clone $query;
    $last = clone $query;
    $random = clone $query;

    // We will construct the queries differently depending on whether the sorting
    // criteria is a field or a base table property.
    // If we found a field value earlier, we know we're dealing with a field
    if (isset($field_value)) {

      // set the conditions
      // first and last queries
      $first
        ->join('field_data_' . $sort, $sort, 'n.nid = ' . $sort . '.entity_id AND ' . $sort . '.entity_type = :entity_type', array(
        ':entity_type' => 'node',
      ));
      $first
        ->condition($sort . '.' . $sort . '_value', $field_value, $before);
      $last
        ->join('field_data_' . $sort, $sort, 'n.nid = ' . $sort . '.entity_id AND ' . $sort . '.entity_type = :entity_type', array(
        ':entity_type' => 'node',
      ));
      $last
        ->condition($sort . '.' . $sort . '_value', $field_value, $after);

      // previous and next queries
      $prev
        ->join('field_data_' . $sort, $sort, 'n.nid = ' . $sort . '.entity_id AND ' . $sort . '.entity_type = :entity_type', array(
        ':entity_type' => 'node',
      ));
      $prev
        ->condition(db_or()
        ->condition($sort . '.' . $sort . '_value', $field_value, $before)
        ->condition(db_and()
        ->condition($sort . '.' . $sort . '_value', $field_value, '=')
        ->condition('n.nid', $node->nid, $before)));
      $next
        ->join('field_data_' . $sort, $sort, 'n.nid = ' . $sort . '.entity_id AND ' . $sort . '.entity_type = :entity_type', array(
        ':entity_type' => 'node',
      ));
      $next
        ->condition(db_or()
        ->condition($sort . '.' . $sort . '_value', $field_value, $after)
        ->condition(db_and()
        ->condition($sort . '.' . $sort . '_value', $field_value, '=')
        ->condition('n.nid', $node->nid, $after)));

      // set the ordering
      $first
        ->orderBy($sort . '.' . $sort . '_value', $up);
      $prev
        ->orderBy($sort . '.' . $sort . '_value', $down);
      $next
        ->orderBy($sort . '.' . $sort . '_value', $up);
      $last
        ->orderBy($sort . '.' . $sort . '_value', $down);
    }
    else {

      // Otherwise we assume the variable is a column in the base table (a property).
      // Like above, set the conditions
      // first and last queries
      $first
        ->condition($sort, $node->{$sort}, $before);
      $last
        ->condition($sort, $node->{$sort}, $after);

      // previous and next queries
      $prev
        ->condition(db_or()
        ->condition($sort, $node->{$sort}, $before)
        ->condition(db_and()
        ->condition($sort, $node->{$sort}, '=')
        ->condition('n.nid', $node->nid, $before)));
      $next
        ->condition(db_or()
        ->condition($sort, $node->{$sort}, $after)
        ->condition(db_and()
        ->condition($sort, $node->{$sort}, '=')
        ->condition('n.nid', $node->nid, $after)));

      // set the ordering
      $first
        ->orderBy($sort, $up);
      $prev
        ->orderBy($sort, $down);
      $next
        ->orderBy($sort, $up);
      $last
        ->orderBy($sort, $down);
    }
    $first
      ->orderBy('n.nid', $up);
    $prev
      ->orderBy('n.nid', $down);
    $next
      ->orderBy('n.nid', $up);
    $last
      ->orderBy('n.nid', $down);

    // Execute the queries
    $list = array();
    $list['first'] = $first
      ->execute()
      ->fetchAssoc();
    $list['prev'] = $prev
      ->execute()
      ->fetchAssoc();
    $list['next'] = $next
      ->execute()
      ->fetchAssoc();
    $list['last'] = $last
      ->execute()
      ->fetchAssoc();

    // create random list
    if (variable_get('flippy_random_' . $node->type, NULL)) {
      $random
        ->orderRandom();
      $list['random'] = $random
        ->execute()
        ->fetchAssoc();
    }

    // finally set the current info for themers to use
    $list['current'] = array(
      'nid' => $node->nid,
      'title' => $node->title,
    );
    $master_list[$node->nid] = $list;
  }
  return $master_list[$node->nid];
}