You are here

protected function ViewsQueryAlter::mapConditions in Entity API 8

Maps an entity type's access conditions to views SQL conditions.

Parameters

\Drupal\entity\QueryAccess\ConditionGroup $conditions: The access conditions.

\Drupal\views\Plugin\views\query\Sql $query: The views query.

array $base_table: The base table information.

\Drupal\Core\Field\FieldStorageDefinitionInterface[] $field_storage_definitions: The field storage definitions.

\Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping: The table mapping.

Return value

\Drupal\Core\Database\Query\ConditionInterface The SQL conditions.

1 call to ViewsQueryAlter::mapConditions()
ViewsQueryAlter::alter in src/QueryAccess/ViewsQueryAlter.php
Alters the given views query.

File

src/QueryAccess/ViewsQueryAlter.php, line 157

Class

ViewsQueryAlter
Defines a class for altering views queries.

Namespace

Drupal\entity\QueryAccess

Code

protected function mapConditions(ConditionGroup $conditions, Sql $query, array $base_table, array $field_storage_definitions, DefaultTableMapping $table_mapping) {
  $sql_condition = new SqlCondition($conditions
    ->getConjunction());
  foreach ($conditions
    ->getConditions() as $condition) {
    if ($condition instanceof ConditionGroup) {
      $nested_sql_conditions = $this
        ->mapConditions($condition, $query, $base_table, $field_storage_definitions, $table_mapping);
      $sql_condition
        ->condition($nested_sql_conditions);
    }
    else {
      $field = $condition
        ->getField();
      $property_name = NULL;
      if (strpos($field, '.') !== FALSE) {
        list($field, $property_name) = explode('.', $field);
      }

      // Skip unknown fields.
      if (!isset($field_storage_definitions[$field])) {
        continue;
      }
      $field_storage_definition = $field_storage_definitions[$field];
      if (!$property_name) {
        $property_name = $field_storage_definition
          ->getMainPropertyName();
      }
      $column = $table_mapping
        ->getFieldColumnName($field_storage_definition, $property_name);
      if ($table_mapping
        ->requiresDedicatedTableStorage($field_storage_definitions[$field])) {
        if ($base_table['revision']) {
          $dedicated_table = $table_mapping
            ->getDedicatedRevisionTableName($field_storage_definition);
        }
        else {
          $dedicated_table = $table_mapping
            ->getDedicatedDataTableName($field_storage_definition);
        }

        // Views defaults to LEFT JOIN. For simplicity, we don't try to
        // use an INNER JOIN when it's safe to do so (AND conjunctions).
        $alias = $query
          ->ensureTable($dedicated_table);
      }
      elseif ($base_table['revision'] && !$field_storage_definition
        ->isRevisionable()) {

        // Workaround for #2652652, which causes $query->ensureTable()
        // to not work in this case, due to a missing relationship.
        if ($data_table = $query
          ->getTableInfo($base_table['data_table'])) {
          $alias = $data_table['alias'];
        }
        else {
          $configuration = [
            'type' => 'INNER',
            'table' => $base_table['data_table'],
            'field' => 'id',
            'left_table' => $base_table['alias'],
            'left_field' => 'id',
          ];

          /** @var \Drupal\Views\Plugin\views\join\JoinPluginBase $join */
          $join = Views::pluginManager('join')
            ->createInstance('standard', $configuration);
          $alias = $query
            ->addRelationship($base_table['data_table'], $join, $data_table);
        }
      }
      else {
        $alias = $base_table['alias'];
      }
      $value = $condition
        ->getValue();
      $operator = $condition
        ->getOperator();

      // Using LIKE/NOT LIKE ensures a case insensitive comparison.
      // @see \Drupal\Core\Entity\Query\Sql\Condition::translateCondition().
      $property_definitions = $field_storage_definition
        ->getPropertyDefinitions();
      $case_sensitive = $property_definitions[$property_name]
        ->getSetting('case_sensitive');
      $operator_map = [
        '=' => 'LIKE',
        '<>' => 'NOT LIKE',
      ];
      if ($case_sensitive === FALSE && isset($operator_map[$operator])) {
        $operator = $operator_map[$operator];
        $value = $this->connection
          ->escapeLike($value);
      }
      $sql_condition
        ->condition("{$alias}.{$column}", $value, $operator);
    }
  }
  return $sql_condition;
}