You are here

function hs_taxonomy_views_hierarchical_select_entity_count in Hierarchical Select 6.3

Same name and namespace in other branches
  1. 5.3 modules/hs_taxonomy_views.module \hs_taxonomy_views_hierarchical_select_entity_count()

Implementation of hook_hierarchical_select_entity_count().

File

modules/hs_taxonomy_views.module, line 445
Implementation of the Hierarchical Select API for the Taxonomy module's Views exposed filters.

Code

function hs_taxonomy_views_hierarchical_select_entity_count($item, $params) {
  static $count;
  $current_view = views_get_current_view();
  if (!isset($count[$current_view->name][$item])) {
    $temp_view = $current_view
      ->clone_view();
    $display_id = isset($current_view->current_display) ? $current_view->current_display : 'default';
    $temp_view
      ->set_display($display_id);

    // Disable the pager to get *all* results.
    if (method_exists($temp_view, 'set_use_pager')) {
      $temp_view
        ->set_use_pager(FALSE);
    }
    else {
      $temp_view->set_use_pager = FALSE;
    }

    // Pretend nothing is exposed, otherwise an exposed filters form will also
    // be rendered and thereby cause endless recursion.
    $temp_view->display_handler->has_exposed = 0;

    // Dynamically add an additional filter when
    if ($item != HS_TAXONOMY_VIEWS_ANY_OPTION) {

      // Get an array with all tids: the tid of the currently selected term and
      // all child terms.
      $term = taxonomy_get_term($item);
      $tree = _hs_taxonomy_hierarchical_select_get_tree($term->vid, $term->tid);
      $tids = array(
        $term->tid => $term->tid,
      );
      foreach ($tree as $descendant) {
        $tids[$descendant->tid] = $descendant->tid;
      }
      $id = 'tid_' . implode('-', $tids);
      $temp_view->display[$display_id]->handler
        ->override_option('filters', array(
        $id => array(
          'operator' => 'or',
          'value' => $tids,
          'group' => '0',
          'exposed' => FALSE,
          'expose' => array(
            'operator' => FALSE,
            'label' => '',
          ),
          'type' => 'select',
          'limit' => TRUE,
          'vid' => $params['vid'],
          'id' => $id,
          'table' => 'term_node',
          'field' => 'tid',
          'hierarchy' => 0,
          'override' => array(
            'button' => 'Override',
          ),
          'relationship' => 'none',
          'reduce_duplicates' => 0,
        ),
      ));
    }
    else {

      // Disable the default value, otherwise the <Any> option will actually
      // filter by the default value.
      $filter_id = $params['filter_id'];
      $temp_view->display[$display_id]->display_options['filters'][$filter_id]['value'] = array();
      $temp_view->display[$display_id]->handler->options['filters'][$filter_id]['value'] = array();
      $temp_view->display['default']->display_options['filters'][$filter_id]['value'] = array();
      $temp_view->display['default']->handler->options['filters'][$filter_id]['value'] = array();
    }

    // Build the queries and collect the arguments.
    $temp_view
      ->build($display_id);

    // We only need the count query. We don't care about the actual fields or
    // order of the View.
    $count_query = !empty($temp_view->build_info['count_query']) ? $temp_view->build_info['count_query'] : $temp_view->query->count_query;
    $args = !empty($temp_view->build_info['query_args']) ? $temp_view->build_info['query_args'] : $temp_view->query->query_args;

    // Regenerate the query after we set the distinct flag for the nid field.
    // This unfortunately doesn't work, because Views doesn't create an
    // optimized count query when any of the fields have the distinct flag set.

    //$temp_view->query->fields['nid']['distinct'] = TRUE;

    //$count_query = $temp_view->query->query(TRUE);

    // Due to the above: sneak DISTINCT() in through a string replace ...
    $count_query = str_replace("SELECT node.nid AS nid", "SELECT DISTINCT(node.nid) AS nid", $count_query);

    // Filter by node type if such a filter is configured in the view.
    if (isset($current_view->filter['type'])) {
      $node_types = $current_view->filter['type']->value;
      if (isset($node_types)) {
        $values = '';
        foreach ($node_types as $key => $value) {
          if (empty($values)) {
            $values = '\'' . $value . '\'';
          }
          else {
            $values .= ', \'' . $value . '\'';
          }
        }

        // Use the same sneaky string replace trick once more.
        $count_query = str_replace("WHERE", 'WHERE node.type IN (' . $values . ') AND', $count_query);
      }
    }

    // Apply the same query transformations as view::execute() does.
    $count_query = db_rewrite_sql($count_query, $temp_view->base_table, $temp_view->base_field, array(
      'view' => &$temp_view,
    ));
    $count_query = 'SELECT COUNT(*) FROM (' . $count_query . ') count_alias';

    // Execute the count query.
    $count[$current_view->name][$item] = db_result(db_query($count_query, $args));
  }
  return $count[$current_view->name][$item];
}