statspro.inc in Statistics Pro 6
Same filename and directory in other branches
statspro class for statistics pro module.
File
statspro.incView source
<?php
/**
* @file
* statspro class for statistics pro module.
*
*/
/**
* Manages the data saving and retrieval according to the user defined
* parameters.
*/
class statspro {
private $start_date;
private $end_date;
private $period;
private $last_run;
private $current_field;
protected $fields;
public $absolute_amounts = array(
'pi',
'upi',
'error',
'uerror',
'warning',
'uwarning',
);
/*
* Day results.
*
*/
private $days;
function __construct() {
$this
->set_fields();
}
/**
* Set all available data field to member variable.
*
*/
private function set_fields() {
$this->fields = array(
'nuser' => user_access('administer users') ? l(t('User registrations'), 'admin/user/user') : t('User registrations'),
'auser' => t('User online'),
'nnode' => user_access('administer nodes') ? l(t('New nodes'), 'admin/content/node') : t('New nodes'),
'cnode' => user_access('administer nodes') ? l(t('Changed nodes'), 'admin/content/node') : t('Changed nodes'),
'comment' => user_access('administer comments') ? l(t('Comments'), 'admin/content/comment') : t('Comments'),
'pi' => l(t('Page impressions'), 'admin/reports/hits'),
'upi' => l(t('Page impressions for authenticated users'), 'admin/reports/hits'),
'error' => user_access('access site reports') ? l(t('Errors'), 'admin/reports/dblog') : t('Errors'),
'uerror' => user_access('access site reports') ? l(t('Errors for authenticated users'), 'admin/reports/dblog') : t('Errors for authenticated users'),
'warning' => user_access('access site reports') ? l(t('Warnings'), 'admin/reports/dblog') : t('Warnings'),
'uwarning' => user_access('access site reports') ? l(t('Warnings for authenticated users'), 'admin/reports/dblog') : t('Warnings for authenticated users'),
);
}
/**
* Get data fields.
*
*/
public function get_fields() {
return $this->fields;
}
private function get_calc_fields($whitelist, $blacklist) {
if (is_array($whitelist) && is_array($blacklist)) {
die('whitelist and blacklist cannot be used togther.');
}
elseif (is_array($whitelist)) {
$fields = array();
foreach ($this->fields as $field => $desc) {
if (in_array($field, $whitelist)) {
$fields[$field] = $desc;
}
}
}
elseif (is_array($blacklist)) {
$fields = array();
foreach ($this->fields as $field => $desc) {
if (!in_array($field, $blacklist)) {
$fields[$field] = $desc;
}
}
}
else {
// all fields
$fields = $this->fields;
}
return $fields;
}
public function get_aggregate_stat($mode) {
$rc = FALSE;
if (in_array($mode, $this->absolute_amounts)) {
$rc = array(
'subject' => strip_tags($this->fields[$mode]),
'amount' => db_result(db_query("SELECT SUM(%s) FROM {statspro}", $mode)),
);
}
elseif ($mode == 'users') {
$rc = array(
'subject' => t('Amount of users'),
'amount' => db_result(db_query("SELECT COUNT(*) FROM {users}")),
);
}
elseif ($mode == 'terms') {
$rc = array(
'subject' => t('Terms'),
'amount' => $this
->generate_term_stats(),
);
}
elseif ($mode == 'nodes') {
$rc = array(
'subject' => t('Amount of nodes'),
'amount' => db_result(db_query("SELECT COUNT(*) FROM {node} WHERE status=1")),
);
}
elseif ($mode == 'node_types') {
$rc = array(
'subject' => t('Amount of node types'),
'amount' => db_result(db_query("SELECT COUNT(*) FROM {node_type}")),
);
}
elseif ($mode == 'comments') {
$rc = array(
'subject' => t('Amount of comments'),
'amount' => db_result(db_query("SELECT COUNT(*) FROM {comments}")),
);
}
elseif ($mode == 'aliases') {
$rc = array(
'subject' => t('Amount of aliases'),
'amount' => db_result(db_query("SELECT COUNT(*) FROM {url_alias}")),
);
}
elseif ($mode == 'sessions') {
$rc = array(
'subject' => t('Amount of sessions'),
'amount' => db_result(db_query("SELECT COUNT(*) FROM {sessions}")),
);
}
elseif ($mode == 'modules') {
$modules = module_rebuild_cache();
$amount = 0;
foreach ($modules as $values) {
if ($values->status) {
$amount++;
}
}
$rc = array(
'subject' => t('Amount of modules'),
'amount' => $amount,
);
}
return $rc;
}
/**
*
* Get statictics for output.
*
*/
public function get_stats($period, $start_date, $end_date, $whitelist = NULL, $blacklist = NULL) {
$this->period = $period;
$this->start_date = $start_date;
$this->end_date = $end_date;
$with_data = FALSE;
// build field list
$fields = $this
->get_calc_fields($whitelist, $blacklist);
// initialize values
$data = array();
foreach ($fields as $field => $desc) {
$data[$field] = 0;
}
// get values
$sql = 'SELECT
day, nuser, auser, nnode, cnode, comment, pi,
upi, error, uerror, warning, uwarning
FROM {statspro} WHERE ' . $this
->get_period();
$result = db_query($sql);
while ($row = db_fetch_array($result)) {
foreach ($fields as $field => $desc) {
$data[$field] += $row[$field];
if (!$with_data && $row[$field] > 0) {
$with_data = TRUE;
}
}
}
if ($with_data) {
// prepare return array
$rows = array();
foreach ($fields as $field => $desc) {
$rows[] = array(
$desc,
$data[$field],
);
}
return $rows;
}
}
/**
* Returns a string with a WHERE compliant representation of a min and max day
* selection.
*
* @param <int> $min
* @param <int> $max
* @return <string> SQL min and max WHERE.
*/
protected function get_min_max_period($min, $max) {
return sprintf('(day >= %u AND day <= %u)', $min, $max);
}
/**
* Returns a SQL WHERE for the selected week.
*
* Weeks starts at mondays and ends at sundays.
*
* For date('w') we get 0 (for Sunday) through 6 (for Saturday).
*
* @param <int> $reference Defines the selected week.
* @return <string> SQL min and max WHERE for week.
*/
protected function get_week_from_reference($reference) {
$min = $this
->get_first_day_of_week_from_reference($reference);
$day_of_week = date('w', $reference);
$max = $day_of_week == 0 ? 'today' : 'next sunday';
$max = date('Ymd', strtotime($max, $reference));
return $this
->get_min_max_period($min, $max);
}
/**
* Returns a YYYYMMDD date representation of the first day of same the week
* as the reference day.
*
* @param <int> $reference A timestamp representaing the reference day.
* @return <int> First day of the same week of the reference day.
*/
protected function get_first_day_of_week_from_reference($reference) {
$day_of_week = date('w', $reference);
$first = $day_of_week == 1 ? 'today' : 'previous monday';
$first = date('Ymd', strtotime($first, $reference));
return $first;
}
/**
* Returns a SQL WHERE for the selected month.
*
* @param <int> $reference Defines the selected month.
* @return <string> SQL min and max WHERE for month.
*/
protected function get_month_from_reference($reference) {
$min = $this
->get_first_day_of_month_from_reference($reference);
$max = $this
->get_last_day_of_month_from_reference($reference);
return $this
->get_min_max_period($min, $max);
}
/**
* Returns a YYYYMMDD date representation of the first day of same the month
* as the reference day.
*
* @param <int> $reference A timestamp representaing the reference day.
* @return <int> First day of the same month of the reference day.
*/
protected function get_first_day_of_month_from_reference($reference) {
$year = date('Y', $reference);
$month = date('m', $reference);
$first = $year . '-' . $month . '-01';
$first = date('Ymd', strtotime($first));
return $first;
}
/**
* Returns a YYYYMMDD date representation of the last day of same the month
* as the reference day.
*
* @param <int> $reference A timestamp representaing the reference day.
* @return <int> Last day of the same month of the reference day.
*/
protected function get_last_day_of_month_from_reference($reference) {
$year = date('Y', $reference);
$month = date('m', $reference);
$last = $month == 12 ? $year . '-12-31' : sprintf('%04u-%02u-00', $year, $month + 1);
$last = date('Ymd', strtotime($last));
return $last;
}
/**
* Returns a YYYYMMDD date representation of the first day of same the quarter
* as the reference day.
*
* @param <int> $reference A timestamp representaing the reference day.
* @return <int> First day of the same quarter of the reference day.
*/
protected function get_first_day_of_quarter_from_reference($reference) {
$year = date('Y', $reference);
$first_month_of_quarter = $this
->get_first_month_of_quarter_from_reference($reference);
$first = sprintf('%04u%02u01', $year, $first_month_of_quarter);
return $first;
}
/**
* Returns a YYYYMMDD date representation of the last day of same the quarter
* as the reference day.
*
* @param <int> $reference A timestamp representaing the reference day.
* @return <int> Last day of the same quarter of the reference day.
*/
protected function get_last_day_of_quarter_from_reference($reference) {
$year = date('Y', $reference);
$last_month_of_quarter = $this
->get_first_month_of_quarter_from_reference($reference);
$last = $last_month_of_quarter == 12 ? $year . '-12-31' : sprintf('%04u-%02u-00', $year, $last_month_of_quarter + 1);
$last = date('Ymd', strtotime($last));
return $last;
}
/**
* Returns the first month of the same the quarter as the reference day.
*
* @param <int> $reference A timestamp representaing the reference day.
* @return <int> First month of the same quarter of the reference day.
*/
protected function get_first_month_of_quarter_from_reference($reference) {
$month = date('m', $reference);
$first_month = floor(($month - 1) / 3);
$first_month = (int) ($first_month * 3 + 1);
return sprintf('%02u', $first_month);
}
/**
* Returns the last month of same the quarter as the reference day.
*
* @param <int> $reference A timestamp representaing the reference day.
* @return <int> Last month of the same quarter of the reference day.
*/
protected function get_last_month_of_quarter_from_reference($reference) {
$month = date('m', $reference);
$last_month = floor(($month - 1) / 3);
$last_month = (int) (($last_month + 1) * 3);
return sprintf('%02u', $last_month);
}
/**
* Returns a YYYYMMDD date representation of the first day of same the year
* as the reference day.
*
* @param <int> $reference A timestamp representaing the reference day.
* @return <int> First day of the same year of the reference day.
*/
protected function get_first_day_of_year_from_reference($reference) {
$year = date('Y', $reference);
$first = sprintf('%04u0101', $year);
return $first;
}
/**
* Returns a YYYYMMDD date representation of the last day of same the quarter
* as the reference day.
*
* @param <int> $reference A timestamp representaing the reference day.
* @return <int> Last day of the same quarter of the reference day.
*/
protected function get_last_day_of_year_from_reference($reference) {
$year = date('Y', $reference);
$last = sprintf('%04u1231', $year);
return $last;
}
/**
*
* Generate SQL fragment for period query.
*
*/
private function get_period() {
$now = time();
switch ($this->period) {
case 'today':
$today = date('Ymd', $now);
return sprintf('day = %u', $today);
break;
case 'yesterday':
$day = date('Ymd', strtotime('-1 day', $now));
return sprintf('day = %u', $day);
break;
case 'week_current':
$min = $this
->get_first_day_of_week_from_reference($now);
$max = date('Ymd', $now);
return $this
->get_min_max_period($min, $max);
break;
case 'week_last':
$reference = strtotime('-1 week', $now);
return $this
->get_week_from_reference($reference);
break;
case 'week_last2':
$reference = strtotime('-2 week', $now);
return $this
->get_week_from_reference($reference);
break;
case 'month_current':
$min = $this
->get_first_day_of_month_from_reference($now);
$max = date('Ymd', $now);
return $this
->get_min_max_period($min, $max);
break;
case 'month_last':
$reference = strtotime('-1 month', $now);
return $this
->get_month_from_reference($reference);
break;
case 'month_last3':
$reference = strtotime('-3 month', $now);
$min = $this
->get_first_day_of_month_from_reference($reference);
$max = date('Ymd', $now);
return $this
->get_min_max_period($min, $max);
break;
case 'month_last6':
$reference = strtotime('-6 month', $now);
$min = $this
->get_first_day_of_month_from_reference($reference);
$max = date('Ymd', $now);
return $this
->get_min_max_period($min, $max);
break;
case 'quarter_current':
$min = $this
->get_first_day_of_quarter_from_reference($now);
$max = date('Ymd', $now);
return $this
->get_min_max_period($min, $max);
break;
case 'quarter_last':
$reference = strtotime('-3 month', $now);
$min = $this
->get_first_day_of_quarter_from_reference($reference);
$max = $this
->get_last_day_of_quarter_from_reference($reference);
return $this
->get_min_max_period($min, $max);
break;
case 'year_current':
$min = $this
->get_first_day_of_year_from_reference($now);
$max = date('Ymd', $now);
return $this
->get_min_max_period($min, $max);
break;
case 'year_last':
$reference = strtotime('-1 year', $now);
$min = $this
->get_first_day_of_year_from_reference($reference);
$max = $this
->get_last_day_of_year_from_reference($reference);
return $this
->get_min_max_period($min, $max);
break;
default:
watchdog('statspro', "Unknown period '@period'.", array(
'@period' => $this->period,
), WATCHDOG_ERROR);
return FALSE;
break;
}
}
/**
*
* Get data out of drupal source tables.
*
*/
public function get_days_data($last_run = 0) {
// set last run
$this->last_run = $last_run;
// reset days
$this->days = array();
foreach ($this->fields as $field => $desc) {
$this->current_field = $field;
$method = 'get_data_' . $this->current_field;
$this
->{$method}();
}
return $this->days;
}
/**
* Add day data.
*
* @param string $date
* @param int $amount
*/
private function add_day_data($date, $amount) {
if (!empty($date)) {
$amount = (int) $amount;
if (isset($this->days[$date][$this->current_field]) && $this->days[$date][$this->current_field] > 0) {
$this->days[$date][$this->current_field] += $amount;
}
else {
$this->days[$date][$this->current_field] = $amount;
}
}
}
/**
* Returns the number of new users registered per day since the last run.
*/
private function get_data_nuser() {
$result = db_query('SELECT COUNT(*) AS num, DATE(FROM_UNIXTIME(created)) AS dategroup
FROM {users}
WHERE uid > 0
AND created >= %d
GROUP BY dategroup', $this->last_run);
while ($row = db_fetch_array($result)) {
$this
->add_day_data($row['dategroup'], $row['num']);
}
}
/**
* Returns the number of authenticated users that accessed the site per day
* since the last run.
*/
private function get_data_auser() {
$result = db_query('SELECT COUNT(*) AS num, DATE(FROM_UNIXTIME(access)) AS dategroup
FROM {users}
WHERE uid > 0
AND access >= %d
GROUP BY dategroup', $this->last_run);
while ($row = db_fetch_array($result)) {
$this
->add_day_data($row['dategroup'], $row['num']);
}
}
/**
* Returns the number of new nodes created per day since the last run.
*/
private function get_data_nnode() {
$result = db_query('SELECT COUNT(*) AS num, DATE(FROM_UNIXTIME(created)) AS dategroup
FROM {node}
WHERE created >= %d
GROUP BY dategroup', $this->last_run);
while ($row = db_fetch_array($result)) {
$this
->add_day_data($row['dategroup'], $row['num']);
}
}
/**
* Returns the number of nodes changed per day since the last run.
*/
private function get_data_cnode() {
$result = db_query('SELECT COUNT(*) AS num, DATE(FROM_UNIXTIME(changed)) AS dategroup
FROM {node}
WHERE changed >= %d
AND created <> changed
GROUP BY dategroup', $this->last_run);
while ($row = db_fetch_array($result)) {
$this
->add_day_data($row['dategroup'], $row['num']);
}
}
/**
* Count nodes for terms.
*
* @return int
*/
public function generate_term_stats() {
// get nodes
db_query('INSERT INTO {statspro_term} (tid, ncount)
SELECT tid, COUNT(*) AS num
FROM {term_node}
GROUP BY tid');
return db_affected_rows();
}
/**
* Returns the number of new comments created per day since the last run.
*/
private function get_data_comment() {
$result = db_query('SELECT COUNT(*) AS num, DATE(FROM_UNIXTIME(timestamp)) AS dategroup
FROM {comments}
WHERE timestamp >= %d
GROUP BY dategroup', $this->last_run);
while ($row = db_fetch_array($result)) {
$this
->add_day_data($row['dategroup'], $row['num']);
}
}
/**
* Returns the number of total page impressions per day since the last run.
*/
private function get_data_pi() {
$result = db_query('SELECT COUNT(*) AS num, DATE(FROM_UNIXTIME(timestamp)) AS dategroup
FROM {accesslog}
WHERE timestamp >= %d
GROUP BY dategroup', $this->last_run);
while ($row = db_fetch_array($result)) {
$this
->add_day_data($row['dategroup'], $row['num']);
}
}
/**
* Returns the number of page impressions for authenticated users per day
* since the last run.
*/
private function get_data_upi() {
$result = db_query('SELECT COUNT(*) AS num, DATE(FROM_UNIXTIME(timestamp)) AS dategroup
FROM {accesslog}
WHERE timestamp >= %d
AND uid > 0
GROUP BY dategroup', $this->last_run);
while ($row = db_fetch_array($result)) {
$this
->add_day_data($row['dategroup'], $row['num']);
}
}
/**
* Returns the number of total warnings per day since the last run.
*/
private function get_data_warning() {
$result = db_query('SELECT COUNT(*) AS num, DATE(FROM_UNIXTIME(timestamp)) AS dategroup
FROM {watchdog}
WHERE severity = %d
AND timestamp >= %d
GROUP BY dategroup', WATCHDOG_WARNING, $this->last_run);
while ($row = db_fetch_array($result)) {
$this
->add_day_data($row['dategroup'], $row['num']);
}
}
/**
* Returns the number of warnings generated by authenticated users per day
* since the last run.
*/
private function get_data_uwarning() {
$result = db_query('SELECT COUNT(*) AS num, DATE(FROM_UNIXTIME(timestamp)) AS dategroup
FROM {watchdog}
WHERE severity = %d
AND timestamp >= %d
AND uid > 0
GROUP BY dategroup', WATCHDOG_WARNING, $this->last_run);
while ($row = db_fetch_array($result)) {
$this
->add_day_data($row['dategroup'], $row['num']);
}
}
/**
* Returns the number of total errors per day since the last run.
*/
private function get_data_error() {
$result = db_query('SELECT COUNT(*) AS num, DATE(FROM_UNIXTIME(timestamp)) AS dategroup
FROM {watchdog}
WHERE severity = %d
AND timestamp >= %d
GROUP BY dategroup', WATCHDOG_ERROR, $this->last_run);
while ($row = db_fetch_array($result)) {
$this
->add_day_data($row['dategroup'], $row['num']);
}
}
/**
* Returns the number of errors generated by authenticated users per day
* since the last run.
*/
private function get_data_uerror() {
$result = db_query('SELECT COUNT(*) AS num, DATE(FROM_UNIXTIME(timestamp)) AS dategroup
FROM {watchdog}
WHERE severity = %d
AND timestamp >= %d
AND uid > 0
GROUP BY dategroup', WATCHDOG_ERROR, $this->last_run);
while ($row = db_fetch_array($result)) {
$this
->add_day_data($row['dategroup'], $row['num']);
}
}
/**
* Save day information to database.
*
* @param string $date
* @param array $values
*/
public function store_day($date, $values) {
$found = db_result(db_query("SELECT COUNT(*)\n FROM {statspro}\n WHERE day = '%s'", $date));
// update row
if ($found) {
$sql_fields = array();
$sql_values = array();
foreach ($this->fields as $field => $desc) {
$sql_fields[] = $field . ' = ' . $field . ' + %d';
$sql_values[] = isset($values[$field]) ? (int) $values[$field] : 0;
}
// add date to argument array
$sql_values[] = $date;
db_query("UPDATE {statspro} SET\n " . implode(', ', $sql_fields) . "\n WHERE day = '%s'", $sql_values);
}
else {
$sql_fields = array();
$sql_values = array(
$date,
);
$sql_vars = array();
foreach ($this->fields as $field => $desc) {
$sql_fields[] = $field;
$sql_values[] = isset($values[$field]) ? (int) $values[$field] : 0;
$sql_vars[] = '%d';
}
db_query("INSERT INTO {statspro}\n (day, " . implode(',', $sql_fields) . ")\n VALUES('%s', " . implode(', ', $sql_vars) . ")", $sql_values);
}
}
}