You are here

function Sql::ensure_table in Views (for Drupal 7) 8.3

Ensure a table exists in the queue; if it already exists it won't do anything, but if it doesn't it will add the table queue. It will ensure a path leads back to the relationship table.

Parameters

$table: The unaliased name of the table to ensure.

$relationship: The relationship to ensure the table links to. Each relationship will get a unique instance of the table being added. If not specified, will be the primary table.

Drupal\views\Plugin\views\join\JoinPluginBase $join: A Join object (or derived object) to join the alias in.

Return value

The alias used to refer to this specific table, or NULL if the table cannot be ensured.

3 calls to Sql::ensure_table()
Sql::add_field in lib/Drupal/views/Plugin/views/query/Sql.php
Add a field to the query table, possibly with an alias. This will automatically call ensure_table to make sure the required table exists, *unless* $table is unset.
Sql::add_orderby in lib/Drupal/views/Plugin/views/query/Sql.php
Add an ORDER BY clause to the query.
Sql::adjust_join in lib/Drupal/views/Plugin/views/query/Sql.php
Fix a join to adhere to the proper relationship; the left table can vary based upon what relationship items are joined in on.

File

lib/Drupal/views/Plugin/views/query/Sql.php, line 508
Definition of Drupal\views\Plugin\views\query\Sql.

Class

Sql
@todo.

Namespace

Drupal\views\Plugin\views\query

Code

function ensure_table($table, $relationship = NULL, JoinPluginBase $join = NULL) {

  // ensure a relationship
  if (empty($relationship)) {
    $relationship = $this->base_table;
  }

  // If the relationship is the primary table, this actually be a relationship
  // link back from an alias. We store all aliases along with the primary table
  // to detect this state, because eventually it'll hit a table we already
  // have and that's when we want to stop.
  if ($relationship == $this->base_table && !empty($this->tables[$relationship][$table])) {
    return $this->tables[$relationship][$table]['alias'];
  }
  if (!array_key_exists($relationship, $this->relationships)) {
    return FALSE;
  }
  if ($table == $this->relationships[$relationship]['base']) {
    return $relationship;
  }

  // If we do not have join info, fetch it.
  if (!isset($join)) {
    $join = $this
      ->get_join_data($table, $this->relationships[$relationship]['base']);
  }

  // If it can't be fetched, this won't work.
  if (empty($join)) {
    return;
  }

  // Adjust this join for the relationship, which will ensure that the 'base'
  // table it links to is correct. Tables adjoined to a relationship
  // join to a link point, not the base table.
  $join = $this
    ->adjust_join($join, $relationship);
  if ($this
    ->ensure_path($table, $relationship, $join)) {

    // Attempt to eliminate redundant joins.  If this table's
    // relationship and join exactly matches an existing table's
    // relationship and join, we do not have to join to it again;
    // just return the existing table's alias.  See
    // http://groups.drupal.org/node/11288 for details.
    //
    // This can be done safely here but not lower down in
    // queue_table(), because queue_table() is also used by
    // add_table() which requires the ability to intentionally add
    // the same table with the same join multiple times.  For
    // example, a view that filters on 3 taxonomy terms using AND
    // needs to join taxonomy_term_data 3 times with the same join.
    // scan through the table queue to see if a matching join and
    // relationship exists.  If so, use it instead of this join.
    // TODO: Scanning through $this->table_queue results in an
    // O(N^2) algorithm, and this code runs every time the view is
    // instantiated (Views 2 does not currently cache queries).
    // There are a couple possible "improvements" but we should do
    // some performance testing before picking one.
    foreach ($this->table_queue as $queued_table) {

      // In PHP 4 and 5, the == operation returns TRUE for two objects
      // if they are instances of the same class and have the same
      // attributes and values.
      if ($queued_table['relationship'] == $relationship && $queued_table['join'] == $join) {
        return $queued_table['alias'];
      }
    }
    return $this
      ->queue_table($table, $relationship, $join);
  }
}