View source
<?php
namespace Drupal\Core\Config\Entity\Query;
use Drupal\Core\Entity\Query\ConditionBase;
use Drupal\Core\Entity\Query\ConditionInterface;
use Drupal\Core\Entity\Query\QueryException;
class Condition extends ConditionBase {
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' : '=';
}
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 != $match) {
break;
}
}
if ($match) {
$return[$config_name] = $config;
}
}
}
elseif (!$condition_groups || $and) {
$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;
}
public function exists($field, $langcode = NULL) {
return $this
->condition($field, NULL, 'IS NOT NULL', $langcode);
}
public function notExists($field, $langcode = NULL) {
return $this
->condition($field, NULL, 'IS NULL', $langcode);
}
protected function matchArray(array $condition, array $data, array $needs_matching, array $parents = []) {
$parent = array_shift($needs_matching);
if ($parent === '*') {
$candidates = array_keys($data);
}
else {
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;
}
protected function match(array $condition, $value) {
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)) {
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;
}
}