View source
<?php
namespace Drupal\apigee_edge\Entity\Query;
use Drupal\Core\Entity\Query\ConditionBase;
use Drupal\Core\Entity\Query\ConditionInterface;
use Drupal\Core\Entity\Query\QueryException;
class Condition extends ConditionBase implements ConditionInterface {
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);
}
public function compile($query) {
if (empty($this->conditions)) {
return function () {
return TRUE;
};
}
$fold = strtoupper($this->conjunction) === 'AND' ? function (array $filters) : callable {
return function ($item) use ($filters) : bool {
foreach ($filters as $filter) {
if (!$filter($item)) {
return FALSE;
}
}
return TRUE;
};
} : function (array $filters) : callable {
return function ($item) use ($filters) : bool {
foreach ($filters as $filter) {
if ($filter($item)) {
return TRUE;
}
}
return FALSE;
};
};
$filters = [];
foreach ($this->conditions as $condition) {
if ($condition['field'] instanceof ConditionInterface) {
$filters[] = $condition['field']
->compile($query);
}
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_string($condition['value'])) {
$condition['value'] = mb_strtolower($condition['value']);
}
$filters[] = static::matchProperty($condition);
}
}
return count($filters) > 1 ? $fold($filters) : reset($filters);
}
protected static function matchProperty(array $condition) : callable {
return function ($item) use ($condition) : bool {
$value = static::getProperty($item, $condition['field']);
if (is_object($value)) {
return FALSE;
}
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 in_array($value, $condition['value'], TRUE);
case 'NOT IN':
return !in_array($value, $condition['value'], TRUE);
case 'STARTS_WITH':
return mb_strpos($value, $condition['value']) === 0;
case 'CONTAINS':
return mb_strpos($value, $condition['value']) !== FALSE;
case 'ENDS_WITH':
return mb_substr($value, -mb_strlen($condition['value'])) === (string) $condition['value'];
default:
throw new QueryException('Invalid condition operator.');
}
}
return FALSE;
};
}
public static function getProperty($item, string $property) {
$normalized = ucfirst(implode('', array_map('ucfirst', explode('_', $property))));
$getter_candidates = [
"is{$normalized}",
"get{$normalized}",
$normalized,
];
foreach ($getter_candidates as $getter) {
if (method_exists($item, $getter)) {
return call_user_func([
$item,
$getter,
]);
}
}
return NULL;
}
}