public function _buildQuery(array $criteria, $conjunction = 'AND', $tableAlias = null)
{
$iterator = $this->getIterator();
$class = get_class($this);
foreach ([static::STMT_FROM, static::STMT_WHERE, static::STMT_DISTINCT] as $uk) {
if (array_key_exists($uk, $criteria)) {
unset($criteria[$uk]);
}
}
$built = ['where' => []];
$conj = ['$and' => 'AND', '$or' => 'OR'];
$cmp = ['$lt' => '<', '$gt' => '>', '$gte' => '>=', '$lte' => '<=', '$ne' => '<>'];
$func = ['$in' => 'IN(%)', '$nin' => 'NOT IN(%)', '$like' => 'LIKE(%)', '$regex' => 'REGEXP(%)'];
foreach ($criteria as $k => $v) {
if (!is_array($v)) {
throw new InvalidArgumentException(sprintf("Array is expected as argument for %s in %s", $k, $class));
}
if (isset($conj[$k])) {
$b = $this->_buildQuery($v, $conj[$k], $tableAlias);
$built['where'][] = $b['where'];
continue;
}
if (is_numeric($k)) {
list($k, $v) = each($v);
if (isset($conj[$k])) {
$b = $this->_buildQuery($v, $conj[$k], $tableAlias);
$built['where'][] = $b['where'];
continue;
}
}
$field = $iterator->getField($k);
if (empty($field)) {
throw new InvalidArgumentException(sprintf('Field "%s" is not defined for object %s', $k, $class));
}
if (is_array($v)) {
foreach ($v as $t => $vv) {
if ($t == '$exists') {
$built['where'][] = $field->getColumnName($tableAlias) . ((bool) $vv ? ' IS NOT NULL' : ' IS NULL') . ' ';
} else {
if (isset($cmp[$t])) {
$built['where'][] = $field->getColumnName($tableAlias) . ' ' . (!isset($vv) ? ($t == '$ne' || $t == '$lt' || $t == '$gt' ? 'IS NOT ' : 'IS ') . 'NULL' : $cmp[$t] . ' ' . $this->qstr($field, $vv));
} else {
if (isset($func[$t])) {
$tmp = '';
foreach ((array) $vv as $inVal) {
$tmp .= ', ' . (!isset($inVal) ? 'NULL' : $this->qstr($field, $inVal));
}
if ($tmp != '') {
$built['where'][] = $field->getColumnName($tableAlias) . ' ' . str_replace('%', substr($tmp, 2), $func[$t]);
}
} else {
throw new InvalidArgumentException(sprintf("Comparison function '%s' is not defined", $t));
}
}
}
}
} else {
$built['where'][] = $field->getColumnName($tableAlias) . " " . (!isset($v) ? 'IS NULL ' : '= ' . $this->qstr($field, $v));
}
}
if (!empty($built['where'])) {
$built['where'] = join(" {$conjunction} ", $built['where']);
if ($conjunction == 'OR') {
$built['where'] = "(" . $built['where'] . ")";
}
} else {
$built['where'] = '1=1';
}
return $built;
}