protected function data_implode($data, $conjunctor, $outer_conjunctor = null)
{
$wheres = array();
foreach ($data as $key => $value) {
$type = gettype($value);
if (preg_match("/^(AND|OR)(\\s+#.*)?\$/i", $key, $relation_match) && $type == 'array') {
$wheres[] = 0 !== count(array_diff_key($value, array_keys(array_keys($value)))) ? '(' . $this->data_implode($value, ' ' . $relation_match[1]) . ')' : '(' . $this->inner_conjunct($value, ' ' . $relation_match[1], $conjunctor) . ')';
} else {
preg_match('/(#?)([\\w\\.]+)(\\[(\\>|\\>\\=|\\<|\\<\\=|\\!|\\<\\>|\\>\\<|\\!?~)\\])?/i', $key, $match);
$column = $this->column_quote($match[2]);
if (isset($match[4])) {
$operator = $match[4];
if ($operator == '!') {
switch ($type) {
case 'NULL':
$wheres[] = $column . ' IS NOT NULL';
break;
case 'array':
$wheres[] = $column . ' NOT IN (' . $this->array_quote($value) . ')';
break;
case 'integer':
case 'double':
$wheres[] = $column . ' != ' . $value;
break;
case 'boolean':
$wheres[] = $column . ' != ' . ($value ? '1' : '0');
break;
case 'string':
$wheres[] = $column . ' != ' . $this->fn_quote($key, $value);
break;
}
}
if ($operator == '<>' || $operator == '><') {
if ($type == 'array') {
if ($operator == '><') {
$column .= ' NOT';
}
if (is_numeric($value[0]) && is_numeric($value[1])) {
$wheres[] = '(' . $column . ' BETWEEN ' . $value[0] . ' AND ' . $value[1] . ')';
} else {
$wheres[] = '(' . $column . ' BETWEEN ' . $this->quote($value[0]) . ' AND ' . $this->quote($value[1]) . ')';
}
}
}
if ($operator == '~' || $operator == '!~') {
if ($type == 'string') {
$value = array($value);
}
if (!empty($value)) {
$like_clauses = array();
foreach ($value as $item) {
if ($operator == '!~') {
$column .= ' NOT';
}
if (preg_match('/^(?!%).+(?<!%)$/', $item)) {
$item = '%' . $item . '%';
}
$like_clauses[] = $column . ' LIKE ' . $this->fn_quote($key, $item);
}
$wheres[] = implode(' OR ', $like_clauses);
}
}
if (in_array($operator, array('>', '>=', '<', '<='))) {
if (is_numeric($value)) {
$wheres[] = $column . ' ' . $operator . ' ' . $value;
} elseif (strpos($key, '#') === 0) {
$wheres[] = $column . ' ' . $operator . ' ' . $this->fn_quote($key, $value);
} else {
$wheres[] = $column . ' ' . $operator . ' ' . $this->quote($value);
}
}
} else {
switch ($type) {
case 'NULL':
$wheres[] = $column . ' IS NULL';
break;
case 'array':
$wheres[] = $column . ' IN (' . $this->array_quote($value) . ')';
break;
case 'integer':
case 'double':
$wheres[] = $column . ' = ' . $value;
break;
case 'boolean':
$wheres[] = $column . ' = ' . ($value ? '1' : '0');
break;
case 'string':
$wheres[] = $column . ' = ' . $this->fn_quote($key, $value);
break;
}
}
}
}
return implode($conjunctor . ' ', $wheres);
}