public static function get($paramarray = array())
{
$params = array();
$fns = array('get_results', 'get_row', 'get_value');
$select = '';
// what to select -- by default, everything
foreach (User::default_fields() as $field => $value) {
$select .= '' == $select ? "{users}.{$field}" : ", {users}.{$field}";
}
// defaults
$orderby = 'id ASC';
$nolimit = true;
// Put incoming parameters into the local scope
$paramarray = Utils::get_params($paramarray);
// Transact on possible multiple sets of where information that is to be OR'ed
if (isset($paramarray['where']) && is_array($paramarray['where'])) {
$wheresets = $paramarray['where'];
} else {
$wheresets = array(array());
}
$wheres = array();
$join = '';
if (isset($paramarray['orderby'])) {
$orderby = $paramarray['orderby'];
}
if (isset($paramarray['where']) && is_string($paramarray['where'])) {
$wheres[] = $paramarray['where'];
} else {
foreach ($wheresets as $paramset) {
// safety mechanism to prevent empty queries
$where = array();
$paramset = array_merge((array) $paramarray, (array) $paramset);
$default_fields = User::default_fields();
unset($default_fields['id']);
foreach ($default_fields as $field => $scrap) {
if (!isset($paramset[$field])) {
continue;
}
switch ($field) {
default:
$where[] = "{$field} = ?";
$params[] = $paramset[$field];
}
}
if (isset($paramset['info']) && is_array($paramset['info'])) {
$join .= 'INNER JOIN {userinfo} ON {users}.id = {userinfo}.user_id';
foreach ($paramset['info'] as $info_name => $info_value) {
$where[] = '{userinfo}.name = ? AND {userinfo}.value = ?';
$params[] = $info_name;
$params[] = $info_value;
}
}
if (isset($paramset['group']) && is_array($paramset['group'])) {
$join .= ' INNER JOIN {users_groups} ON {users}.id = {users_groups}.user_id';
foreach ($paramset['group'] as $group) {
$group_id = UserGroup::get_by_name($group)->id;
$where[] = '{users_groups}.group_id = ?';
$params[] = $group_id;
}
}
if (isset($paramset['id'])) {
if (is_array($paramset['id'])) {
array_walk($paramset['id'], function (&$a) {
$a = intval($a);
});
$where[] = "{users}.id IN (" . implode(',', array_fill(0, count($paramset['id']), '?')) . ")";
$params = array_merge($params, $paramset['id']);
} else {
$where[] = "{users}.id = ?";
$params[] = (int) $paramset['id'];
}
}
if (isset($paramset['not:id'])) {
if (is_array($paramset['not:id'])) {
array_walk($paramset['not:id'], function (&$a) {
$a = intval($a);
});
$where[] = "{users}.id NOT IN (" . implode(',', array_fill(0, count($paramset['not:id']), '?')) . ")";
$params = array_merge($params, $paramset['not:id']);
} else {
$where[] = "{users}.id != ?";
$params[] = (int) $paramset['not:id'];
}
}
if (isset($paramset['criteria'])) {
if (isset($paramset['criteria_fields'])) {
// Support 'criteria_fields' => 'author,ip' rather than 'criteria_fields' => array( 'author', 'ip' )
if (!is_array($paramset['criteria_fields']) && is_string($paramset['criteria_fields'])) {
$paramset['criteria_fields'] = explode(',', $paramset['criteria_fields']);
}
} else {
$paramset['criteria_fields'] = array('username');
}
$paramset['criteria_fields'] = array_unique($paramset['criteria_fields']);
// this regex matches any unicode letters (\p{L}) or numbers (\p{N}) inside a set of quotes (but strips the quotes) OR not in a set of quotes
preg_match_all('/(?<=")([\\p{L}\\p{N}]+[^"]*)(?=")|([\\p{L}\\p{N}]+)/u', $paramset['criteria'], $matches);
$where_search = array();
foreach ($matches[0] as $word) {
foreach ($paramset['criteria_fields'] as $criteria_field) {
$where_search[] .= "( LOWER( {users}.{$criteria_field} ) LIKE ? )";
$params[] = '%' . MultiByte::strtolower($word) . '%';
}
}
if (count($where_search) > 0) {
$where[] = '(' . implode(" \nOR\n ", $where_search) . ')';
}
}
if (count($where) > 0) {
$wheres[] = ' (' . implode(' AND ', $where) . ') ';
}
}
}
// Get any full-query parameters
$possible = array('fetch_fn', 'count', 'nolimit', 'limit', 'offset');
foreach ($possible as $varname) {
if (isset($paramarray[$varname])) {
${$varname} = $paramarray[$varname];
}
}
if (isset($fetch_fn)) {
if (!in_array($fetch_fn, $fns)) {
$fetch_fn = $fns[0];
}
} else {
$fetch_fn = $fns[0];
}
// is a count being request?
if (isset($count)) {
$select = "COUNT({$count})";
$fetch_fn = 'get_value';
$orderby = '';
}
if (isset($limit)) {
unset($nolimit);
$limit = " LIMIT {$limit}";
if (isset($offset)) {
$limit .= " OFFSET {$offset}";
}
}
if (isset($nolimit)) {
$limit = '';
}
$query = '
SELECT ' . $select . ' FROM {users} ' . $join;
if (count($wheres) > 0) {
$query .= ' WHERE ' . implode(" \nOR\n ", $wheres);
}
$query .= ($orderby == '' ? '' : ' ORDER BY ' . $orderby) . $limit;
DB::set_fetch_mode(\PDO::FETCH_CLASS);
DB::set_fetch_class('User');
$results = DB::$fetch_fn($query, $params, 'User');
if ('get_results' != $fetch_fn) {
// return the results
return $results;
} elseif (is_array($results)) {
$c = __CLASS__;
$return_value = new $c($results);
$return_value->get_param_cache = $paramarray;
return $return_value;
}
}