You are here

class Condition in Drupal 9

Same name in this branch
  1. 9 core/lib/Drupal/Core/Condition/Annotation/Condition.php \Drupal\Core\Condition\Annotation\Condition
  2. 9 core/lib/Drupal/Core/Database/Query/Condition.php \Drupal\Core\Database\Query\Condition
  3. 9 core/lib/Drupal/Core/Config/Entity/Query/Condition.php \Drupal\Core\Config\Entity\Query\Condition
  4. 9 core/lib/Drupal/Core/Entity/KeyValueStore/Query/Condition.php \Drupal\Core\Entity\KeyValueStore\Query\Condition
  5. 9 core/lib/Drupal/Core/Entity/Query/Sql/Condition.php \Drupal\Core\Entity\Query\Sql\Condition
  6. 9 core/lib/Drupal/Core/Entity/Query/Null/Condition.php \Drupal\Core\Entity\Query\Null\Condition
  7. 9 core/lib/Drupal/Core/Entity/Query/Sql/pgsql/Condition.php \Drupal\Core\Entity\Query\Sql\pgsql\Condition
  8. 9 core/tests/fixtures/database_drivers/module/corefake/src/Driver/Database/corefakeWithAllCustomClasses/Condition.php \Drupal\corefake\Driver\Database\corefakeWithAllCustomClasses\Condition
Same name and namespace in other branches
  1. 8 core/lib/Drupal/Core/Config/Entity/Query/Condition.php \Drupal\Core\Config\Entity\Query\Condition
  2. 10 core/lib/Drupal/Core/Config/Entity/Query/Condition.php \Drupal\Core\Config\Entity\Query\Condition

Defines the condition class for the config entity query.

Hierarchy

Expanded class hierarchy of Condition

See also

\Drupal\Core\Config\Entity\Query\Query

1 file declares its use of Condition
Condition.php in core/lib/Drupal/Core/Entity/KeyValueStore/Query/Condition.php
6 string references to 'Condition'
ConditionAggregate::compile in core/lib/Drupal/Core/Entity/Query/Sql/ConditionAggregate.php
Compiles this conditional clause.
Connection::condition in core/lib/Drupal/Core/Database/Connection.php
Prepares and returns a CONDITION query object.
Connection::getDriverClass in core/lib/Drupal/Core/Database/Connection.php
Gets the driver-specific override class if any for the specified class.
ConnectionTest::providerGetDriverClass in core/tests/Drupal/Tests/Core/Database/ConnectionTest.php
Data provider for testGetDriverClass().
core.data_types.schema.yml in core/config/schema/core.data_types.schema.yml
core/config/schema/core.data_types.schema.yml

... See full list

File

core/lib/Drupal/Core/Config/Entity/Query/Condition.php, line 14

Namespace

Drupal\Core\Config\Entity\Query
View source
class Condition extends ConditionBase {

  /**
   * {@inheritdoc}
   */
  public function compile($configs) {
    $and = strtoupper($this->conjunction) == 'AND';
    $single_conditions = [];
    $condition_groups = [];
    foreach ($this->conditions as $condition) {
      if ($condition['field'] instanceof ConditionInterface) {
        $condition_groups[] = $condition;
      }
      else {
        if (!isset($condition['operator'])) {
          $condition['operator'] = is_array($condition['value']) ? 'IN' : '=';
        }

        // Lowercase condition value(s) for case-insensitive matches.
        if (is_array($condition['value'])) {
          $condition['value'] = array_map('mb_strtolower', $condition['value']);
        }
        elseif (!is_bool($condition['value'])) {
          $condition['value'] = mb_strtolower($condition['value']);
        }
        $single_conditions[] = $condition;
      }
    }
    $return = [];
    if ($single_conditions) {
      foreach ($configs as $config_name => $config) {
        foreach ($single_conditions as $condition) {
          $match = $this
            ->matchArray($condition, $config, explode('.', $condition['field']));

          // If AND and it's not matching, then the rest of conditions do not
          // matter and this config object does not match.
          // If OR and it is matching, then the rest of conditions do not
          // matter and this config object does match.
          if ($and != $match) {
            break;
          }
        }
        if ($match) {
          $return[$config_name] = $config;
        }
      }
    }
    elseif (!$condition_groups || $and) {

      // If there were no single conditions then either:
      // - Complex conditions, OR: need to start from no entities.
      // - Complex conditions, AND: need to start from all entities.
      // - No complex conditions (AND/OR doesn't matter): need to return all
      //   entities.
      $return = $configs;
    }
    foreach ($condition_groups as $condition) {
      $group_entities = $condition['field']
        ->compile($configs);
      if ($and) {
        $return = array_intersect_key($return, $group_entities);
      }
      else {
        $return = $return + $group_entities;
      }
    }
    return $return;
  }

  /**
   * {@inheritdoc}
   */
  public function exists($field, $langcode = NULL) {
    return $this
      ->condition($field, NULL, 'IS NOT NULL', $langcode);
  }

  /**
   * {@inheritdoc}
   */
  public function notExists($field, $langcode = NULL) {
    return $this
      ->condition($field, NULL, 'IS NULL', $langcode);
  }

  /**
   * Matches for an array representing one or more config paths.
   *
   * @param array $condition
   *   The condition array as created by the condition() method.
   * @param array $data
   *   The config array or part of it.
   * @param array $needs_matching
   *   The list of config array keys needing a match. Can contain config keys
   *   and the * wildcard.
   * @param array $parents
   *   The current list of parents.
   *
   * @return bool
   *   TRUE when the condition matched to the data else FALSE.
   */
  protected function matchArray(array $condition, array $data, array $needs_matching, array $parents = []) {
    $parent = array_shift($needs_matching);
    if ($parent === '*') {
      $candidates = array_keys($data);
    }
    else {

      // Avoid a notice when calling match() later.
      if (!isset($data[$parent])) {
        $data[$parent] = NULL;
      }
      $candidates = [
        $parent,
      ];
    }
    foreach ($candidates as $key) {
      if ($needs_matching) {
        if (is_array($data[$key])) {
          $new_parents = $parents;
          $new_parents[] = $key;
          if ($this
            ->matchArray($condition, $data[$key], $needs_matching, $new_parents)) {
            return TRUE;
          }
        }
        elseif ($condition['operator'] === 'IS NULL') {
          return TRUE;
        }
      }
      elseif ($this
        ->match($condition, $data[$key])) {
        return TRUE;
      }
    }
    return FALSE;
  }

  /**
   * Perform the actual matching.
   *
   * @param array $condition
   *   The condition array as created by the condition() method.
   * @param string $value
   *   The value to match against.
   *
   * @return bool
   *   TRUE when matches else FALSE.
   */
  protected function match(array $condition, $value) {

    // "IS NULL" and "IS NOT NULL" conditions can also deal with array values,
    // so we return early for them to avoid problems.
    if (in_array($condition['operator'], [
      'IS NULL',
      'IS NOT NULL',
    ], TRUE)) {
      $should_be_set = $condition['operator'] === 'IS NOT NULL';
      return $should_be_set === isset($value);
    }
    if (isset($value)) {

      // We always want a case-insensitive match.
      if (!is_bool($value)) {
        $value = mb_strtolower($value);
      }
      switch ($condition['operator']) {
        case '=':
          return $value == $condition['value'];
        case '>':
          return $value > $condition['value'];
        case '<':
          return $value < $condition['value'];
        case '>=':
          return $value >= $condition['value'];
        case '<=':
          return $value <= $condition['value'];
        case '<>':
          return $value != $condition['value'];
        case 'IN':
          return array_search($value, $condition['value']) !== FALSE;
        case 'NOT IN':
          return array_search($value, $condition['value']) === FALSE;
        case 'STARTS_WITH':
          return strpos($value, $condition['value']) === 0;
        case 'CONTAINS':
          return strpos($value, $condition['value']) !== FALSE;
        case 'ENDS_WITH':
          return substr($value, -strlen($condition['value'])) === (string) $condition['value'];
        default:
          throw new QueryException('Invalid condition operator.');
      }
    }
    return FALSE;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
Condition::compile public function Compiles this conditional clause. Overrides ConditionInterface::compile
Condition::exists public function Queries for the existence of a field. Overrides ConditionInterface::exists
Condition::match protected function Perform the actual matching.
Condition::matchArray protected function Matches for an array representing one or more config paths.
Condition::notExists public function Queries for the nonexistence of a field. Overrides ConditionInterface::notExists
ConditionBase::condition public function Adds a condition. Overrides ConditionInterface::condition
ConditionFundamentals::$conditions protected property Array of conditions.
ConditionFundamentals::$conjunction protected property The conjunction of this condition group.
ConditionFundamentals::$namespaces protected property List of potential namespaces of the classes belonging to this condition.
ConditionFundamentals::$query protected property The query this condition belongs to. 1
ConditionFundamentals::conditions public function
ConditionFundamentals::count public function
ConditionFundamentals::getConjunction public function
ConditionFundamentals::__clone public function Implements the magic __clone function.
ConditionFundamentals::__construct public function Constructs a Condition object.