1

Case: users set flags on content using Flag module (flags are per user, not global).

Requirement: after a period of time the system should automatically unset these flags using Rules module.

The obvious way to do this would seem to be: when cron runs, fetch all instances of flag that have been set, and unset them.

(In actuality, only flags that were created x days ago will be unset; newer flags will be left. But I can't get the basic setup and this will just be a condition.)

    Event: Cron maintenance tasks are performed
    Action: ?? 

I can't see a way to get/fetch all flags of a certain type that have been set.

(Obviously I could choose the action Execute custom PHP code and write some code against the relevant flag table... but surely there's a cleaner way of doing this..?)

Can anyone help?

1

Use the Rules module together with Rules Scheduler (a sub-module of it), as explained in the steps below.

Step 1: Create a Rules Component to unflag a node

Create a Rules Component to unflag (= unset the flag) of a node that was flagged by a given user. Assume you give it a machine name like rules_unflag_node_flagged_by_a_user. Use parameters like flagged_node (for the node) and flagging_user (for the user who flagged). And assume that the machine name of your flag is my_special_flag.

Here is a Rules Component (in Rules export format) you can use for this (using the above mentioned machine names):

{ "rules_unflag_node_flagged_by_a_user" : {
    "LABEL" : "Unflag node flagged by a user",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "flag", "rules" ],
    "USES VARIABLES" : {
      "flagging_user" : { "label" : "Flagging user", "type" : "user" },
      "flagged_node" : { "label" : "Node to be unflagged", "type" : "node" }
    },
    "DO" : [
      { "flag_unflagnode" : {
          "flag" : "my_special_flag",
          "node" : [ "flagged-node" ],
          "flagging_user" : [ "flagging_user" ],
          "permission_check" : "1"
        }
      },
      { "drupal_message" : { "message" : "Node unflagged for user  [flagging-user:name] (uid=[flagging-user:uid])" } }
    ]
  }
}

Use the Rules "Import Component" facility (located within /admin/config/workflow/rules/components) to import it in your own environment, but make sure the machine name of the flag matches with your own machine name for it.

Consider the Rules Action drupal_message as for QA-testing only (remove it in your final version, no need for that Rules Action).

Step 2: Schedule the execution of the Rules Component

Create a rule like so:

  • Rules Event = After a node gets flagged (with the flag you're already using).
  • Rules Action = Schedule the execution of the Rules Component (created in Step 1), for execution within x days.

Here is a Rule (in Rules export format) you can use for this (using the above mentioned machine names):

{ "rules_schedule_the_unflag_a_node_flagged_by_a_user" : {
    "LABEL" : "Schedule the unflag a node flagged by a user",
    "PLUGIN" : "reaction rule",
    "ACTIVE" : false,
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "rules_scheduler", "flag" ],
    "ON" : { "flag_flagged_my_special_flag" : [] },
    "DO" : [
      { "schedule_delete" : {
          "component" : "rules_unflag_node_flagged_by_a_user",
          "task" : "[flag:name]-[flagged-node:nid]-[flagging-user:uid]"
        }
      },
      { "schedule" : {
          "component" : "rules_unflag_node_flagged_by_a_user",
          "date" : "+7 day",
          "identifier" : "[flag:name]-[flagged-node:nid]-[flagging-user:uid]",
          "param_flagging_user" : [ "flagging-user" ],
          "param_flagged_node" : [ "flagged-node" ]
        }
      }
    ]
  }
}

Some more details about the above rule:

  • The scheduled date of the Rules Component is within 7 days (cfr. your "x" days).
  • The identifier of the scheduled task is [flag:name]-[flagged-node:nid]-[flagging-user:uid], which should ensure the scheduled tasks have unique identifiers.
  • The schedule_delete that is part of this rule is to ensure that previously "scheduled" reminders will get removed if for whatever reason the same user flags the same node with the same flag (so that it only triggers 1 reminder, and with the most recent date).

Use the Rules "Import" facility (located within /admin/config/workflow/rules) to import it in your own environment, but make sure the machine name of the flag matches with your own machine name for it (and review the value of +7 day to fit your value of "X days"). Then use the Rules UI to enable the rule (it's disabled by default).

Step 3: Run cron periodically

Rules scheduled for execution using Rules Scheduler, will actually be executed "next time cron runs" (after the scheduled date/time has arrived). So make sure to (a) actually run cron and (b) schedule the execution a bit before the cron job will actually run them.

Example: if you want the unflagging to happen every night at (say) 2 am, schedule the Rules Component's execution at (say) 1:55 am, and make sure cron runs at 2 am sharp.

Notes:

  1. The above logic will only apply to nodes flagged by users after the Rule component (Step 1) and Rule (Step 3) was activated.
  2. No need for custom PHP code.

PS: I'm assuming this question is about D7.

| improve this answer | |
  • Comments are not for extended discussion; this conversation has been moved to chat. – Clive Jun 22 '16 at 13:46

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.