2

I have a rule that deducts 1 point from users viewing a node, however the problem is that users with a negative balance can still view a node. So I would want to prevent this.

I'm using Drupal 7 with modules Rules and User Points.

Any suggestions?

  • Do you want the user to still be able to see the content in Views and/or any menus, or should the content be completely unavailable to them? – Chapabu Sep 18 '15 at 14:52
1

Your question actually contains 2 challenges:

  1. Which Rules Event to use?
  2. Check the current balance of user points of the user?

Read on for an answer to address each of those challenges.

1. Rules Event to use

If you'd use Rules event node_view, then you're too late, because the node is already being viewed (which is exactly what you want to prevent). Instead you need to use (System) event "Drupal is initializing" (= init), which is actually BEFORE the node is actually being viewed.

2. Check current balance of user points

However, you also want to disallow viewing nodes for users who have a negative user points balance. The challenge with that is that there is no out-of-the-box Rules Condition to check that balance.

Have a look at this Rules example (in Rules export format):

{ "rules_stop_node_access_for_user_with_negative_points" : {
    "LABEL" : "Disallow node/* access for a user with negative points",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "userpoints_rules", "rules", "rules_conditional" ],
    "ON" : { "init" : [] },
    "IF" : [
      { "text_matches" : {
          "text" : [ "site:current-page:path" ],
          "match" : "node\/\\d+$",
          "operation" : "regex"
        }
      }
    ],
    "DO" : [
      { "userpoints_rules_get_current_points" : {
          "USING" : { "user" : [ "site:current-user" ], "tid" : "all" },
          "PROVIDE" : { "loaded_points" : { "total_points" : "Number of points in all categories together" } }
        }
      },
      { "CONDITIONAL" : [
          {
            "IF" : { "data_is" : { "data" : [ "total-points" ], "op" : "\u003C", "value" : "0" } },
            "DO" : [
              { "drupal_message" : { "message" : "You have insufficient points (you only have [total-points:value] points ...)." } },
              { "redirect" : { "url" : "no_access" } }
            ]
          }
        ]
      }
    ]
  }
}

The Rules Condition added here, is to only perform the Rules Action for attempts to browse a path like node/* (adapt to what fits for your case).

This rule retrieves, as the very first Rules Action (not Rules Condition!) the current amount of user points of a user. If it is negative, it will display an appropriate message starting with "You have insufficient points ...", and it redirects to a relative path like no_access (adapt to what fits for it).

This rule uses the Conditional Rules module, though you could also rework the Rules Action to performing Rules Components (in which you add the appropriate Rules Conditions), so that you don't need this extra module.

The clue to make this rule work is the very first Rules Action "Load user points of a user". Refer to my answer to "How to access current amount of earned userpoints in a Rules Condition?" for more details on this.

-2

Add rule for node_view with custom php as condition. In condition check for negative points. If negative points, condition returns true. Execute custom php with drupal_access_denied()

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.