1 handlers.inc views_many_to_one_helper::ensure_my_table()

Override ensure_my_table so we can control how this joins in. The operator actually has influence over joining.

File

core/modules/views/includes/handlers.inc, line 781
Defines the various handler objects to help build and display views.

Class

views_many_to_one_helper
This many to one helper object is used on both arguments and filters.

Code

function ensure_my_table() {
  if (!isset($this->handler->table_alias)) {
    // Case 1: Operator is an 'or' and we're not reducing duplicates.
    // We hence get the absolute simplest:
    $field = $this->handler->relationship . '_' . $this->handler->table . '.' . $this->handler->field;
    if ($this->handler->operator == 'or' && empty($this->handler->options['reduce_duplicates'])) {
      if (empty($this->handler->options['add_table']) && empty($this->handler->view->many_to_one_tables[$field])) {
        $join = $this->get_join();
        if (isset($join)) {
          $join->type = 'LEFT';
          // INNER joins are slightly faster; use them when we know it's safe.
          $group = isset($this->handler->options['group']) ? $this->handler->options['group'] : FALSE;
          $group_type = !empty($group) ? $this->handler->query->where[$group]['type'] : FALSE;
          $plugin_id = isset($this->handler->options['plugin_id']) ? $this->handler->options['plugin_id'] : FALSE;
          // @todo Figure out why taxonomy_index_tid is being special-cased here.
          // See: https://github.com/backdrop/backdrop-issues/issues/5225
          if ($group === FALSE || $group_type == 'AND' && $plugin_id && $plugin_id != 'taxonomy_index_tid') {
            $join->type = 'INNER';
          }
        }
        $this->handler->table_alias = $this->handler->query->ensure_table($this->handler->table, $this->handler->relationship, $join);
        $this->handler->view->many_to_one_tables[$field] = $this->handler->value;
      }
      else {
        $join = $this->get_join();
        $join->type = 'LEFT';
        if (!empty($this->handler->view->many_to_one_tables[$field])) {
          foreach ($this->handler->view->many_to_one_tables[$field] as $value) {
            $join->extra = array(
              array(
                'field' => $this->handler->real_field,
                'operator' => '!=',
                'value' => $value,
                'numeric' => !empty($this->handler->definition['numeric']),
              ),
            );
          }
        }

        $this->handler->table_alias = $this->add_table($join);
      }

      return $this->handler->table_alias;
    }

    // Case 2: it's anything but an 'or'.
    // Clone the join for each table:
    $this->handler->table_aliases = array();
    $values = $this->handler->operator === 'not' ? array($this->handler->value) : $this->handler->value;
    foreach ($values as $value) {
      $join = $this->get_join();
      if ($this->handler->operator == 'and') {
        $join->type = 'INNER';
      }
      if (empty($join->extra)) {
        $join->extra = array();
      }
      $join->extra[] = array(
        'field' => $this->handler->real_field,
        'value' => $value,
        'numeric' => !empty($this->handler->definition['numeric']),
      );
      if (($this->handler->is_a_group() && is_array($value)) || $this->handler->operator === 'not') {
        $value = serialize($value);
      }
      // The table alias needs to be unique to this value across the
      // multiple times the filter or argument is called by the view.
      if (!isset($this->handler->view->many_to_one_aliases[$field][$value])) {
        if (!isset($this->handler->view->many_to_one_count[$this->handler->table])) {
          $this->handler->view->many_to_one_count[$this->handler->table] = 0;
        }
        $this->handler->view->many_to_one_aliases[$field][$value] = $this->handler->table . '_value_' . ($this->handler->view->many_to_one_count[$this->handler->table]++);
        $alias = $this->handler->table_aliases[$value] = $this->add_table($join, 
        $this->handler->view->many_to_one_aliases[$field][$value]);
        // and set table_alias to the first of these.
        if (empty($this->handler->table_alias)) {
          $this->handler->table_alias = $alias;
        }
      }
      else {
        $this->handler->table_aliases[$value] = $this->handler->view->many_to_one_aliases[$field][$value];
      }
    }
  }
  return $this->handler->table_alias;
}