You are here

function user_stats_cron in User Stats 6

Same name and namespace in other branches
  1. 5 user_stats.module \user_stats_cron()
  2. 7 user_stats.module \user_stats_cron()

Implementation of hook_cron().

We slowly work through all users without a post count updating them.

File

./user_stats.module, line 396
User Stats provides commonly requested user statistics for themers. These are:

Code

function user_stats_cron() {
  if (variable_get('user_stats_rebuild_stats', TRUE) && (variable_get('user_stats_count_posts', TRUE) || variable_get('user_stats_count_comments', TRUE))) {
    $sql = "SELECT uid FROM {users} WHERE uid NOT IN\n      (SELECT uid FROM {user_stats_values} WHERE name = 'post_count')";

    // Update 25 users per cron run.
    $result = db_query_range($sql, 0, variable_get('user_stats_user_per_cron', '25'));
    $users_updated = FALSE;
    while ($update_user = db_fetch_object($result)) {
      user_stats_post_count_update('reset', $update_user->uid);
      $users_updated = TRUE;
    }

    // If all users have been updated we'll avoid running this expensive
    // query again by setting the following flag!
    if (!$users_updated) {
      variable_set('user_stats_rebuild_stats', FALSE);
    }
  }

  // Fire rules day_older event.
  // This may seem grossly inefficient, but testing showed that, even firing
  // the event for ~100 users, takes less than a second to run when there are
  // no rules using this event. With a rule (that adds a role if the user has
  // been a member for over 1,000 days) cron took an extra ~40 seconds to run.
  // Basically, this has no potential to harm a site's performance, unless a
  // rule is configured.
  // Having said this: if there's a better way, please raise a bug report!
  if (module_exists('rules')) {

    // We're selecting the user, their calculated age, and their "last known age"
    // as calculated the last time this function was run.
    $sql = "SELECT u.uid, FLOOR((%d-created)/(60*60*24)) AS age, lka.value AS\n    last_known_age FROM {users} u ";
    $sql .= "LEFT JOIN {user_stats_values} lka ON lka.uid = u.uid AND\n    lka.name = 'last_known_age'";

    // ((last cron - created) - (time() - created)) > one day
    $sql .= "WHERE (FLOOR((%d-created)/(60*60*24))-FLOOR((%d-created)/(60*60*24)))>0\n      AND u.uid>0";
    $result = db_query($sql, time(), time(), variable_get('cron_last', time()));
    $reset_user_count = 0;
    while ($update_user = db_fetch_object($result)) {

      // If the user's calculated age is the same as their "last known age", that means
      // This user has been already updated today, and processed at some point by this
      // script. Maybe cron failed or something, and that's why they're being loaded
      // again? Regardless, the event was already triggered for them - we're not going
      // to trigger it again.
      if ($update_user->age != $update_user->last_known_age) {

        // We need to ensure the user_stats "last_known_age" value for this user is
        // accurate because that is what the Rules event trigger will actually provide
        // as an argument as the official "user's age".
        if (isset($update_user->last_known_age)) {

          // Update existing last known age
          db_query("UPDATE {user_stats_values} SET value = %d\n          WHERE name = 'last_known_age' AND uid = %d", $update_user->age, $update_user->uid);
        }
        else {

          // If there isn't a value insert it.
          db_query("INSERT INTO {user_stats_values} (name, uid, value)\n          VALUES ('last_known_age', %d, %d)", $update_user->uid, $update_user->age);
        }
        rules_invoke_event('user_stats_day_older', $update_user->uid);
      }
    }
  }
  if (variable_get('user_stats_track_ips', TRUE)) {

    // Delete items from the IP log that are past expiry.
    db_query("DELETE FROM {user_stats_ips} WHERE first_seen_timestamp < %d", time() - variable_get('user_stats_flush_ips_timer', 31536000));
  }
}