You are here

public function SelectTranslation::query in Select translation 8

Executes the query.

Use a query that doesn't use correlated sub-queries. Thus executing faster for larger data sets.

Overrides FilterPluginBase::query

File

src/Plugin/views/filter/SelectTranslation.php, line 138

Class

SelectTranslation
Views select translation filter handler.

Namespace

Drupal\select_translation\Plugin\views\filter

Code

public function query() {
  $default_language = \Drupal::languageManager()
    ->getDefaultLanguage()
    ->getId();
  $current_language = \Drupal::languageManager()
    ->getCurrentLanguage(LanguageInterface::TYPE_INTERFACE)
    ->getId();

  // Limit the language list to default only, if the option was selected and
  // default_language == current_language.
  if ($this->options['default_language_only'] && $default_language == $current_language) {
    $list = [
      $default_language,
    ];
  }
  else {
    if ($this->value == 'list') {
      $mode = $this->options['priorities'];
    }
    else {
      $mode = $this->value;
    }
    $list = select_translation_parse_mode($mode);
  }

  // Now build the query.
  $query = $this->query;
  $alias = $query
    ->ensureTable('node_field_data');
  $condition_holder = new Condition('OR');
  $i = 0;
  $exclude = [];

  // Now go through each language.
  foreach ($list as $language) {
    $and = new Condition('AND');

    // Before adding the currently processed language exclude the ones
    // already processed in previous iterations.
    foreach ($exclude as $e) {
      $and
        ->isNull("{$e}.nid");
    }
    if ($language != 'original') {

      // Create a Views join on the node table, and add it as a relationship.
      // This is used to find if there are translations of a certain language.
      $sub_query_alias = 'nt' . $i;
      $exclude[] = $sub_query_alias;
      ++$i;

      // Because domain module uses node_access, and rewrites the query to add
      // exists clauses for each left joined node table (maybe specific to all
      // node access modules), thus breaking the listing, we wrap the table in
      // a sub-query, avoiding the exists clause.
      $join = $this
        ->nodeAccessJoin($language, $alias, $sub_query_alias);

      // Add the join as a relationship.
      $query
        ->addRelationship($sub_query_alias, $join, 'node_field_data');

      // Include nodes of specified language.
      $and
        ->condition("{$alias}.langcode", $language);
    }
    else {

      // Include nodes that are the base of a translation (aka original).
      $and
        ->condition("{$alias}.default_langcode", 1);
    }
    $condition_holder
      ->condition($and);
  }

  // Include site default nodes in place of unpublished translations.
  if ($this->options['include_content_with_unpublished_translation']) {
    $sub_query_alias = 'nt' . $i;

    // Join with the currently selected language.
    $join = $this
      ->nodeAccessJoin($current_language, 'node_field_data', $sub_query_alias);

    // Add the join as a relationship.
    $query
      ->addRelationship($sub_query_alias, $join, 'node_field_data');

    // The default language node will be selected, if the current language
    // (translated) node is unpublished.
    $and = (new Condition('AND'))
      ->condition("{$alias}.langcode", $default_language)
      ->condition("{$sub_query_alias}.status", Drupal\node\NodeInterface::NOT_PUBLISHED);
    $condition_holder
      ->condition($and);
  }

  // Add in the conditions.
  $query
    ->addWhere($this->options['group'], $condition_holder);
}