You are here

statspro.inc in Statistics Pro 6

Same filename and directory in other branches
  1. 6.2 statspro.inc

statspro class for statistics pro module.

File

statspro.inc
View 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);
    }
  }

}

Classes

Namesort descending Description
statspro Manages the data saving and retrieval according to the user defined parameters.