You are here

protected function TaxonomyIndexDepthQueryTrait::addSubQueryJoin in Drupal 9

Same name and namespace in other branches
  1. 10 core/modules/taxonomy/src/TaxonomyIndexDepthQueryTrait.php \Drupal\taxonomy\TaxonomyIndexDepthQueryTrait::addSubQueryJoin()

Builds a performant depth subquery and adds it as a join to the query.

Parameters

string|array $tids: The terms ID(s) to do a depth search for.

2 calls to TaxonomyIndexDepthQueryTrait::addSubQueryJoin()
IndexTidDepth::query in core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php
Set up the query for this argument.
TaxonomyIndexTidDepth::query in core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTidDepth.php
Add this filter to the query.

File

core/modules/taxonomy/src/TaxonomyIndexDepthQueryTrait.php, line 44

Class

TaxonomyIndexDepthQueryTrait
Builds a performant depth subquery and adds it as a join to the query.

Namespace

Drupal\taxonomy

Code

protected function addSubQueryJoin($tids) : void {
  $connection = $this->query
    ->getConnection();
  $operator = is_array($tids) ? 'IN' : '=';

  // Create the depth 0 subquery.
  $subquery = $connection
    ->select('taxonomy_index', 'tn');
  $subquery
    ->addField('tn', 'nid');
  $subquery
    ->condition('tn.tid', $tids, $operator);
  if ($this->options['depth'] !== 0) {

    // Set $left_field and $right_field depending on whether we are traversing
    // up or down the hierarchy.
    if ($this->options['depth'] > 0) {
      $left_field = 'parent_target_id';
      $right_field = 'entity_id';
    }
    else {
      $left_field = 'entity_id';
      $right_field = 'parent_target_id';
    }

    // Traverse the hierarchy to check the child or parent terms.
    foreach (range(1, abs($this->options['depth'])) as $count) {
      $union_query = $connection
        ->select('taxonomy_index', 'tn');
      $union_query
        ->addField('tn', 'nid');
      $left_join = "[tn].[tid]";
      if ($this->options['depth'] > 0) {
        $union_query
          ->join('taxonomy_term__parent', "th", "{$left_join} = [th].[entity_id]");
        $left_join = "[th].[{$left_field}]";
      }
      foreach (range(1, $count) as $inner_count) {
        $union_query
          ->join('taxonomy_term__parent', "th{$inner_count}", "{$left_join} = [th{$inner_count}].[{$right_field}]");
        $left_join = "[th{$inner_count}].[{$left_field}]";
      }
      $union_query
        ->condition("th{$inner_count}.entity_id", $tids, $operator);
      $subquery
        ->union($union_query);
    }
  }

  // Add the subquery as a join.
  $definition['left_table'] = $this->tableAlias;
  $definition['left_field'] = $this->realField;
  $definition['field'] = 'nid';
  $definition['type'] = 'INNER';
  $definition['adjusted'] = TRUE;
  $definition['table formula'] = $subquery;
  $join = Views::pluginManager('join')
    ->createInstance('standard', $definition);

  // There is no $base as we are joining to a query.
  $this->query
    ->addRelationship('taxonomy_index_depth', $join, NULL, $this->relationship);
}