public static function get($paramarray = array())
{
$params = array();
$fns = array('get_results', 'get_row', 'get_value');
$select_ary = array();
$select_distinct = array();
// Put incoming parameters into the local scope
$paramarray = Utils::get_params($paramarray);
if ($paramarray instanceof \ArrayIterator) {
$paramarray = $paramarray->getArrayCopy();
}
$select_fields = LogEntry::default_fields();
if (!isset($paramarray['return_data'])) {
unset($select_fields['data']);
}
foreach ($select_fields as $field => $value) {
if (preg_match('/(?:(?P<table>[\\w\\{\\}]+)\\.)?(?P<field>\\w+)(?:(?:\\s+as\\s+)(?P<alias>\\w+))?/i', $field, $fielddata)) {
if (empty($fielddata['table'])) {
$fielddata['table'] = '{log}';
}
if (empty($fielddata['alias'])) {
$fielddata['alias'] = $fielddata['field'];
}
}
$select_ary[$fielddata['alias']] = "{$fielddata['table']}.{$fielddata['field']} AS {$fielddata['alias']}";
$select_distinct[$fielddata['alias']] = "{$fielddata['table']}.{$fielddata['field']}";
}
// 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());
}
$query = Query::create('{log}');
$query->select($select_ary);
if (isset($paramarray['where']) && is_string($paramarray['where'])) {
$query->where()->add($paramarray['where']);
}
foreach ($wheresets as $paramset) {
$where = new QueryWhere();
$paramset = array_merge((array) $paramarray, (array) $paramset);
if (isset($paramset['id'])) {
$where->in('{log}.id', $paramset['id'], 'log_id', 'intval');
}
if (isset($paramset['user_id'])) {
$where->in('{log}.user_id', $paramset['user_id'], 'log_user_id', 'intval');
}
if (isset($paramset['severity']) && 'any' != LogEntry::severity_name($paramset['severity'])) {
$where->in('{log}.severity_id', $paramset['severity'], 'log_severity_id', function ($a) {
return LogEntry::severity($a);
});
}
if (isset($paramset['type_id'])) {
$where->in('{log}.type_id', $paramset['type_id'], 'log_type_id', 'intval');
}
if (isset($paramset['module'])) {
$paramset['module'] = Utils::single_array($paramset['module']);
$qry = Query::create('{log_types}');
$qry->select('{log_types}.id')->distinct();
$qry->where()->in('{log_types}.module', $paramset['module'], 'log_subquery_module');
$where->in('{log}.type_id', $qry, 'log_module');
}
if (isset($paramset['type'])) {
$paramset['type'] = Utils::single_array($paramset['type']);
$qry = Query::create('{log_types}');
$qry->select('{log_types}.id')->distinct();
$qry->where()->in('{log_types}.type', $paramset['type'], 'log_subquery_type');
$where->in('{log}.type_id', $qry, 'log_type');
}
if (isset($paramset['ip'])) {
$where->in('{log}.ip', $paramset['ip']);
}
/* do searching */
if (isset($paramset['criteria'])) {
// 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('/(?<=")(\\w[^"]*)(?=")|([:\\w]+)/u', $paramset['criteria'], $matches);
foreach ($matches[0] as $word) {
if (preg_match('%^id:(\\d+)$%i', $word, $special_crit)) {
$where->in('{log}.id', $special_crit[1], 'log_special_criteria');
} else {
$crit_placeholder = $query->new_param_name('criteria');
$where->add("( LOWER( {log}.message ) LIKE :{$crit_placeholder}", array($crit_placeholder => '%' . MultiByte::strtolower($word) . '%'));
}
}
}
/**
* Build the pubdate
* If we've got the day, then get the date.
* If we've got the month, but no date, get the month.
* If we've only got the year, get the whole year.
*
* @todo Ensure that we've actually got all the needed parts when we query on them
*/
if (isset($paramset['day']) && isset($paramset['month']) && isset($paramset['year'])) {
$start_date = sprintf('%d-%02d-%02d', $paramset['year'], $paramset['month'], $paramset['day']);
$start_date = DateTime::create($start_date);
$where->add('timestamp BETWEEN :start_date AND :end_date', array('start_date' => $start_date->sql, 'end_date' => $start_date->modify('+1 day -1 second')->sql));
} elseif (isset($paramset['month']) && isset($paramset['year'])) {
$start_date = sprintf('%d-%02d-%02d', $paramset['year'], $paramset['month'], 1);
$start_date = DateTime::create($start_date);
$where->add('timestamp BETWEEN :start_date AND :end_date', array('start_date' => $start_date->sql, 'end_date' => $start_date->modify('+1 month -1 second')->sql));
} elseif (isset($paramset['year'])) {
$start_date = sprintf('%d-%02d-%02d', $paramset['year'], 1, 1);
$start_date = DateTime::create($start_date);
$where->add('timestamp BETWEEN :start_date AND :end_date', array('start_date' => $start_date->sql, 'end_date' => $start_date->modify('+1 year -1 second')->sql));
}
// Concatenate the WHERE clauses
$query->where()->add($where);
}
// Default parameters.
$orderby = 'timestamp DESC, id DESC';
// $limit = Options::get( 'pagination' );
// Get any full-query parameters
$paramarray = new SuperGlobal($paramarray);
$extract = $paramarray->filter_keys('orderby', 'fetch_fn', 'count', 'month_cts', 'nolimit', 'index', 'limit', 'offset');
foreach ($extract as $key => $value) {
${$key} = $value;
}
if (isset($index) && is_numeric($index)) {
$offset = (intval($index) - 1) * intval($limit);
}
if (isset($fetch_fn)) {
if (!in_array($fetch_fn, $fns)) {
$fetch_fn = $fns[0];
}
} else {
$fetch_fn = $fns[0];
}
if (isset($count)) {
$query->set_select("COUNT({$count})");
$fetch_fn = isset($paramarray['fetch_fn']) ? $fetch_fn : 'get_value';
$orderby = null;
$groupby = null;
$having = null;
}
// If the month counts are requested, replace the select clause
if (isset($paramset['month_cts'])) {
// @todo shouldn't this hand back to habari to convert to DateTime so it reflects the right timezone?
$query->set_select('MONTH(FROM_UNIXTIME(timestamp)) AS month, YEAR(FROM_UNIXTIME(timestamp)) AS year, COUNT(*) AS ct');
$groupby = 'year, month';
if (!isset($paramarray['orderby'])) {
$orderby = 'year, month';
}
}
if (isset($nolimit) || isset($month_cts)) {
$limit = null;
}
// Define the LIMIT, OFFSET, ORDER BY, GROUP BY if they exist
if (isset($limit)) {
$query->limit($limit);
}
if (isset($offset)) {
$query->offset($offset);
}
if (isset($orderby)) {
$query->orderby($orderby);
}
if (isset($groupby)) {
$query->groupby($groupby);
}
/*
if(isset($paramarray['type'])) {
print_r($query->params());
print_r($query->get());die();
}
*/
/* All SQL parts are constructed, on to real business! */
DB::set_fetch_mode(\PDO::FETCH_CLASS);
DB::set_fetch_class('LogEntry');
$results = DB::$fetch_fn($query->get(), $query->params(), 'LogEntry');
// If the fetch callback function is not get_results,
// return an EventLog ArrayObject filled with the results as LogEntry objects.
if ('get_results' != $fetch_fn) {
return $results;
} elseif (is_array($results)) {
$c = __CLASS__;
$return_value = new $c($results);
$return_value->get_param_cache = $paramarray;
return $return_value;
}
}