Elgg\Database\PrivateSettingsTable::getWhereSql PHP Method

getWhereSql() private method

Returns private setting name and value SQL where/join clauses for entities
private getWhereSql ( string $table, array | null $names = null, array | null $values = null, array | null $pairs = null, string $pair_operator = 'AND', string $name_prefix = '' ) : array
$table string Entities table name
$names array | null Array of names
$values array | null Array of values
$pairs array | null Array of names / values / operands
$pair_operator string Operator for joining pairs where clauses
$name_prefix string A string to prefix all names with
return array
    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;
    }