2

My main problem is very similar to How to grant userpoints to users who perform a login 5 days consecutively?: I would like to keep track of the number of consecutive days on which verified users accessed the website. Therefore, I added an integer user field Consecutive days and created the following Rule that hooks into "visiting the website" (see How to hook into "visiting the website"?):

{ "rules_extra_consecutive_day_online" : {
    "LABEL" : "Extra consecutive day online",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "rules_scheduler" ],
    "ON" : { "init" : [] },
    "IF" : [
      { "user_has_role" : {
          "account" : [ "site:current-user" ],
          "roles" : { "value" : { "2" : "2" } }
        }
      },
      { "OR" : [
          { "data_is" : {
              "data" : [ "site:current-user:field-consecutive-days" ],
              "value" : "0"
            }
          },
          { "AND" : [
              { "data_is" : {
                  "data" : [ "site:current-user:last-access" ],
                  "op" : "\u003C",
                  "value" : "today midnight -1 second"
                }
              },
              { "data_is" : {
                  "data" : [ "site:current-user:last-access" ],
                  "op" : "\u003E",
                  "value" : "yesterday midnight"
                }
              }
            ]
          }
        ]
      }
    ],
    "DO" : [
      { "data_calc" : {
          "USING" : {
            "input_1" : [ "site:current-user:field-consecutive-days" ],
            "op" : "+",
            "input_2" : "1"
          },
          "PROVIDE" : { "result" : { "new_streak" : "New streak" } }
        }
      },
      { "data_set" : {
          "data" : [ "site:current-user:field-consecutive-days" ],
          "value" : [ "new-streak" ]
        }
      },
      { "schedule" : {
          "component" : "rules_reset_consecutive_days",
          "date" : "+2 days midnight",
          "param_user" : [ "site:current-user" ]
        }
      },
    ]
  }
}

The scheduled Rules component at the end of the Rule resets Consecutive days to 0 if necessary:

{ "rules_reset_consecutive_days" : {
    "LABEL" : "Reset consecutive days",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "USES VARIABLES" : { "user" : { "label" : "User", "type" : "user" } },
    "IF" : [
      { "data_is" : {
          "data" : [ "user:last-access" ],
          "op" : "\u003C",
          "value" : "yesterday midnight -1 second"
        }
      }
    ],
    "DO" : [
      { "data_set" : {
          "data" : [ "user:field-consecutive-days" ],
          "value" : "0"
        }
      }
    ]
  }
}

This seems to work relatively well, but there is a catch: the Last access field is not updated at every page request. As a result, users can increase their Consecutive days during a few minutes right after midnight by refreshing the page again and again.

How can I fix this issue? Should I override the Last access field at every page request or is there an alternative way to correctly update Consecutive days?

  • @Pierre.Vriens: Haha, thank you for the upvote. ;-) Yes, those relative formats are like magic (see php.net/manual/en/datetime.formats.relative.php). – Jeroen Jan 18 '17 at 17:37
  • Maybe you should post a self answered question also to illustrate some of that magic with some other Rules Example(s)? How about something with a title like "How to take advantage in Rules of relative date formats?" (+link to that php.net page). Give it some thought (and notify me if you ever do)! – Pierre.Vriens Jan 18 '17 at 17:41
1

Overriding the built-in Last access field is not possible with Rules, so I added a new user Date field Last day online that stores a day, month and year. Recall that I had already created another user integer field Consecutive days. Here is the magical Rule:

{ "rules_extra_consecutive_day_online" : {
    "LABEL" : "Extra consecutive day online",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "rules_scheduler" ],
    "ON" : { "init" : [] },
    "IF" : [
      { "NOT user_has_role" : {
          "account" : [ "site:current-user" ],
          "roles" : { "value" : { "1" : "1", "3" : "3" } }
        }
      },
      { "OR" : [
          { "data_is" : { "data" : [ "site:current-user:field-consecutive-days" ], "value" : "0" } },
          { "data_is" : {
              "data" : [ "site:current-user:field-last-day-online" ],
              "value" : "yesterday midnight"
            }
          }
        ]
      }
    ],
    "DO" : [
      { "data_calc" : {
          "USING" : {
            "input_1" : [ "site:current-user:field-consecutive-days" ],
            "op" : "+",
            "input_2" : "1"
          },
          "PROVIDE" : { "result" : { "new_consecutive_days" : "New consecutive days" } }
        }
      },
      { "data_set" : {
          "data" : [ "site:current-user:field-consecutive-days" ],
          "value" : [ "new-consecutive-days" ]
        }
      },
      { "data_set" : {
          "data" : [ "site:current-user:field-last-day-online" ],
          "value" : "today midnight"
        }
      },
      { "schedule" : {
          "component" : "rules_reset_consecutive_days",
          "date" : "+2 days midnight",
          "param_user" : [ "site:current-user" ]
        }
      }
    ]
  }
}

This is what the Rule does in words:

  • First, check that the current user is verified, and make sure the user's Consecutive days field is zero or the user's Last day online is yesterday.
  • If the above requirements are satisfied, then increase the Consecutive days, change the Last day online to today and schedule the component Reset consecutive days.

Underneath is an export of the mentioned Rules component. It resets the Consecutive days field if the Last day online field is less than yesterday (which means that the user was not online on at least one day).

{ "rules_reset_consecutive_days" : {
    "LABEL" : "Reset consecutive days",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "USES VARIABLES" : { "user" : { "label" : "User", "type" : "user" } },
    "IF" : [
      { "data_is" : {
          "data" : [ "user:field-last-day-online" ],
          "op" : "\u003C",
          "value" : "yesterday midnight"
        }
      }
    ],
    "DO" : [
      { "data_set" : { "data" : [ "user:field-consecutive-days" ], "value" : "0" } }
    ]
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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