You are here

public function Condition::compile in MongoDB 8

Compiles this conditional clause.

Parameters

$query: The query object this conditional clause belongs to.

Overrides ConditionInterface::compile

File

src/Entity/Condition.php, line 49
Contains Drupal\mongodb\Entity\ContentEntityStorage.

Class

Condition

Namespace

Drupal\mongodb\Entity

Code

public function compile($entityType) {

  /** @var \Drupal\Core\Entity\EntityType $entityType */
  $entity_type_id = $this->query
    ->getEntityTypeId();
  $entity_manager = \Drupal::entityManager();
  $langcode_key = \Drupal::entityManager()
    ->getDefinition($entity_type_id)
    ->getKey('langcode');
  $and = strtolower($this->conjunction) == 'and';
  foreach ($this->conditions as $key => $condition) {
    if (isset($condition['langcode'])) {

      /** @var \Drupal\mongodb\Entity\Condition $group */
      $group = new static('and', $this->query);
      $group
        ->condition($condition['field'], $condition['value'], $condition['operator']);
      $group
        ->condition($langcode_key, $condition['langcode']);
      unset($this->conditions[$key]);
      $this
        ->condition($group);
    }
  }
  $field_storage_definitions = $entity_manager
    ->getFieldStorageDefinitions($entity_type_id);
  $find = array();
  $query_index = 0;
  foreach ($this->conditions as $condition) {
    $query_field = $condition['field'];
    if ($query_field instanceof ConditionInterface) {
      if ($compiled = $query_field
        ->compile($entityType)) {
        if ($and) {
          $find['$and'][++$query_index] = $compiled;
        }
        else {
          $find['$or'][] = $compiled;
        }
      }
    }
    else {
      if (!isset($condition['operator'])) {
        $condition['operator'] = is_array($condition['value']) ? '$in' : '=';
      }
      list($field, $column) = explode('.', $query_field, 2) + array(
        1 => '',
      );
      if (!isset($field_storage_definitions[$field])) {
        throw new QueryException(String::format('@column not found', array(
          '@column' => $column,
        )));
      }
      $columns = $field_storage_definitions[$field]
        ->getSchema()['columns'];
      if (!$column) {
        $column = count($columns) == 1 ? array_keys($columns)[0] : 'value';
      }
      $translated_condition = $this
        ->translateCondition($condition, $columns[$column]['type']);
      if ($and) {
        if (isset($find['$and'][$query_index]['values']['$elemMatch'][$field]['$elemMatch'][$column])) {
          $this
            ->merge($find['$and'][$query_index]['values']['$elemMatch'][$field]['$elemMatch'][$column], $translated_condition);
        }
        else {

          // The first $elemMatch is required to keep unspecified langcode
          // conditions within the same translation, the second is to keep
          // the same fields within the same delta.
          $find['$and'][$query_index]['values']['$elemMatch'][$field]['$elemMatch'][$column] = $translated_condition;
        }
      }
      else {
        $find['$or'][] = array(
          "values.{$field}.{$column}" => $translated_condition,
        );
      }
    }
  }
  if ($and) {
    if ($query_index) {
      $find['$and'] = array_values($find['$and']);
    }
    elseif ($find) {
      $find = $find['$and'][0];
    }
  }
  return $find;
}