5

I need to know if a user has performed a login, for example, 5 days consecutively. The reason for this is I want to award User points to them.

For example:

  • User A performs a login on Monday, Tuesday, Wednesday, Thursday and Friday. (granted 10 points)
  • User B performs a login on Monday, Tuesday, Thursday, Friday and Saturday. (no points)

I'm trying to do this with Rules but failed miserably. Any ideas?

Note: I'm trying to use Rules condition to compare my_last_login values against today's date with an offset of -1 days but it always return False.

3
  • 1
    Where are you failing exactly? Rules can definitely hook into user logins. However you might have to code a custom action to do the counting.
    – BetaRide
    Jun 29, 2012 at 9:36
  • I'm trying to use rules condition to compare my_last_login values against today's date with an offset of -1 days but it always return False.
    – haryadimas
    Jul 2, 2012 at 8:11
  • @BetaRide : IMO the key challenge is "5 days consecutively" ... check my answer for more details (why only Rules is not enough). Aug 11, 2016 at 17:20

5 Answers 5

2

Actually, this is what I am trying to build right now. Use the hook_user_login() with the following code:

global $user;
$last_access = $user->access;
// if last_access is today, do nothing
$yesterday_start    = mktime(0, 0, 0,date('m'), date('d')) - (60*60*24);
$yesterday_end  = $yesterday_start + (60*60*24)-1;  


// if last access is yesterday, increment counter
if ($last_access > $yesterday_start && $last_access < $yesterday_end) {
  //increment counter
} 
// if last access is before yesterday, set counter = 1
else if ($last_access < $yesterday_start) {
  $counter = 1;
}

if ($counter == 5) {
  // put you magic code here
  // set the counter to 1 
}

The $counter can be something like variable_get(). Alternatively, I guess that you can put the code above in your Rules, if you don't want to write a module. In both cases, however, the code will not be executed if the user leaves his browser logged in.

2
  • This looks very promising. I wonder where should i put this? In the Rules action and set the trigger to 'User has logged in'?
    – haryadimas
    Jul 2, 2012 at 8:14
  • I have put this inside a hook_user_login() hook. I guess that this will also work if you do what you describe. In both cases, however, the code will not be executed if the user leaves his browser logged in.
    – Mike
    Jul 2, 2012 at 19:18
3

Statistics module in the core would work in this case.

1

Using the Rules module to solve this challenge is indeed part of the solution. But the key part of your challenge is that you want a Rules Action to be triggered, for a Rules Event (= user performs a login) which:

  1. has to be repeated
  2. within a specified timeframe
  3. which don't all happen at the very same moment.

Rules is great (actually amazing), but it does not support any of the 3 bullets above. So far the bad news ...

However, your question seems like a perfect case for using the Goals module (disclosure: I'm the maintainer of it). Below is a possible configuration for it, using Goals.

Configure a goal

Navigate to the relative path admin/config/goals/manage and use the link "Add a goal" to define just 1 goal, with a description (say):

Perform a login, 5 days consecutively.

Configure a task

To achieve the above goal, define the Task(s) to be completed. Even though there could be multiple tasks to be completed for a single goal, in your case you just need 1. It's simply Perform a login.

Obviously, that doesn't take into account the 5 days consecutively-part of your question. For that you would use some of the more advanced ways to use (configure) Goals, i.e. by using these optional configuration options for this specific task:

  • this task has to be repeated multiple times: in your case 5 times.
  • this task requires some amount of time to expire in between any 2 similar tasks: in your case, if a user performs a login/logout multiple times a day, only the first one of every day counts.
  • this task must be completed within a specific time frame (a number of times, expressed in hours, days or weeks): in your case 5 days.

Track progress while performing tasks

To track the progress made by a single user to complete this task, you only have to write an appropriate rule, using the Rules module, to record relevant events happening in your site, which are related to the completion of the task to reach the goal.

For the goal/task described above, you'd only need 1 (extremely basic) rule, which would look like so:

  • Rules Event = After a user performs a login.
  • Rules Action = Record a task for Goals (obviously, the task to be recorded is "Perform a login"). This is where part of the Goals magic happens, such as verifying the requirements in the optional task configuration options for a task (only once a day, etc).

Note: if the user leaves his/her browser logged in, then using this Rules Event might not be the most appropriate event. If you'd replace that event by "Drupal is Initializing" (within "System"), then such rule will be triggered for any path that the user visits. Optionally you may want to combine that Rules Event with an extra Rules Condition "User has role, with role = authenticated", so that the Rules Action(s) are only performed for logged in users.

Use Rules to process completed goals

After all tasks specific to a goal are completed by a user, the goal is automagically marked as completed. But, that's where it gets really interesting: you can also create additional rules that will be triggered (Rules Event) when a goal is completed by a user. With that, the answer to your question is extremely easy: perform a Rules Action to "... grant userpoints to the user who completed the goal" ... which is exactly what your question is about, no?

More info

Refer to my answer to "How to implement gamification in a Drupal site and award incentives?" for additional details about the Goals module.

Note: Using Goals only requires typical administration tasks (configuration), though it does come with various hooks also for custom module development (if you want to).

0

Enable the PHP Filter module.

Add a two fields to user profile (admin/config/people/accounts/fields): for the login counts (name: cons_login_counts, type: integer, default value: 0, permissions: custom(only for admin)) and for the last login date (name: cons_last_login_day, type: text, permissions: custom).

Create a new rule with reacting on event "User has logged in". Add an action "Execute custom PHP code" and put this code:

$user = entity_metadata_wrapper('user', $account);
$login_counts = $user->field_cons_login_counts->value();
$last_login_day = $user->field_cons_last_login_day->value();

$today = date('Y-m-d');
$yesterday = date("Y-m-d", time() - 60 * 60 * 24);

if ($last_login_day == $today)
  return;

if ($last_login_day == $yesterday) {
  $login_counts++;
} else {
  $login_counts = 1;
}

$last_login_day = $today;

if ($login_counts == 5/* and not gived a points to user*/) {
  // give them point
}

$user->field_cons_login_counts = $login_counts;
$user->field_cons_last_login_day = $last_login_day;

$user->save();
1
  • Wow thanks for being very thorough :) This is very helpful.
    – haryadimas
    Jul 2, 2012 at 8:21
-1

Rule has to be triggered when a user is logging in and you need to write Custom PHP Code in the Do Action part of Rule. Like

if(check_user_logins($uid)){
  db_query("UPDATE <table> set points = points + 5 WHERE uid = %d", $uid);
}

function check_user_logins($uid){
  // Code to check consecutive user logins goes here
  if($logins >= 5){
    return TRUE;
  }else{
    return FALSE;
  }
}
2
  • This only checks for 5 logins in general - OP is asking for consecutive logins.
    – Chapabu
    Jun 29, 2012 at 10:16
  • @Chapabu Well I didnt write the entire code ! $logins should be consecutive logins count, thought that was implied and change 5 to X as required.
    – GoodSp33d
    Jun 29, 2012 at 10:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.