private function getWhereSql($table, $names = null, $values = null, $pairs = null, $pair_operator = 'AND', $name_prefix = '')
{
// @todo short circuit test
$return = array('joins' => array(), 'wheres' => array());
$return['joins'][] = "JOIN {$this->table} ps on\n\t\t\t{$table}.guid = ps.entity_guid";
$wheres = array();
// get names wheres
$names_where = '';
if ($names !== null) {
if (!is_array($names)) {
$names = array($names);
}
$sanitised_names = array();
foreach ($names as $name) {
$name = $name_prefix . $name;
$sanitised_names[] = '\'' . $this->db->sanitizeString($name) . '\'';
}
$names_str = implode(',', $sanitised_names);
if ($names_str) {
$names_where = "(ps.name IN ({$names_str}))";
}
}
// get values wheres
$values_where = '';
if ($values !== null) {
if (!is_array($values)) {
$values = array($values);
}
$sanitised_values = array();
foreach ($values as $value) {
// normalize to 0
if (!$value) {
$value = 0;
}
$sanitised_values[] = '\'' . $this->db->sanitizeString($value) . '\'';
}
$values_str = implode(',', $sanitised_values);
if ($values_str) {
$values_where = "(ps.value IN ({$values_str}))";
}
}
if ($names_where && $values_where) {
$wheres[] = "({$names_where} AND {$values_where})";
} elseif ($names_where) {
$wheres[] = "({$names_where})";
} elseif ($values_where) {
$wheres[] = "({$values_where})";
}
// add pairs which must be in arrays.
if (is_array($pairs)) {
// join counter for incremental joins in pairs
$i = 1;
// check if this is an array of pairs or just a single pair.
if (isset($pairs['name']) || isset($pairs['value'])) {
$pairs = array($pairs);
}
$pair_wheres = array();
foreach ($pairs as $index => $pair) {
// @todo move this elsewhere?
// support shortcut 'n' => 'v' method.
if (!is_array($pair)) {
$pair = array('name' => $index, 'value' => $pair);
}
// must have at least a name and value
if (!isset($pair['name']) || !isset($pair['value'])) {
// @todo should probably return false.
continue;
}
if (isset($pair['operand'])) {
$operand = $this->db->sanitizeString($pair['operand']);
} else {
$operand = ' = ';
}
// for comparing
$trimmed_operand = trim(strtolower($operand));
// if the value is an int, don't quote it because str '15' < str '5'
// if the operand is IN don't quote it because quoting should be done already.
if (is_numeric($pair['value'])) {
$value = $this->db->sanitizeString($pair['value']);
} else {
if (is_array($pair['value'])) {
$values_array = array();
foreach ($pair['value'] as $pair_value) {
if (is_numeric($pair_value)) {
$values_array[] = $this->db->sanitizeString($pair_value);
} else {
$values_array[] = "'" . $this->db->sanitizeString($pair_value) . "'";
}
}
if ($values_array) {
$value = '(' . implode(', ', $values_array) . ')';
}
// @todo allow support for non IN operands with array of values.
// will have to do more silly joins.
$operand = 'IN';
} else {
if ($trimmed_operand == 'in') {
$value = "({$pair['value']})";
} else {
$value = "'" . $this->db->sanitizeString($pair['value']) . "'";
}
}
}
$name = $this->db->sanitizeString($name_prefix . $pair['name']);
// @todo The multiple joins are only needed when the operator is AND
$return['joins'][] = "JOIN {$this->table} ps{$i}\n\t\t\t\t\ton {$table}.guid = ps{$i}.entity_guid";
$pair_wheres[] = "(ps{$i}.name = '{$name}' AND ps{$i}.value\n\t\t\t\t\t{$operand} {$value})";
$i++;
}
$where = implode(" {$pair_operator} ", $pair_wheres);
if ($where) {
$wheres[] = "({$where})";
}
}
$where = implode(' AND ', $wheres);
if ($where) {
$return['wheres'][] = "({$where})";
}
return $return;
}