3

I'm using the User Badges and User Points modules. I want that when a user earns a certain number of user points, the user's old badge is replaced by a new one. For this, I have already created a rule with the actions "remove badge" and "add badge". The condition is "execute PHP code" and the code is:

$current_points = userpoints_get_current_points($userpoints_transaction->uid, 'all');
if ($current_points >=7) {
  return true;
}

I also want to display the badge with the username at the top like StackExchange.

Note: Using the above code, it is displaying a message each time when user getting more than 7 user points. I want the message only once.

  • Hello. I don't quite get it - you can run code when condition is met, the real problem is "how to add and remove badges from code?", right? Userpoints and rules are handled already? – Mołot Aug 26 '13 at 7:36
  • Yes, you are right. But i want to add little bit. when condition is met new one is added and old one is removed. – Surendra Prasad Aug 26 '13 at 7:43
  • Adding is good, but please edit your question to make it clear what's the real problem, and put your code in a code block. – Mołot Aug 26 '13 at 7:47
  • Using the above code, It is displaying a message each time when user getting more than 7 points. I want the message only once. If any ideas, please share....... – Surendra Prasad Aug 27 '13 at 11:26
0

Add a new badge

Have a look at this Rules example (in Rules export format), which is a variation of the rule posted by Jeroen:

{ "rules_grant_a_new_badge" : {
    "LABEL" : "Grant a new badge",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "userpoints_rules", "rules", "user_badges", "rules_conditional" ],
    "ON" : { "userpoints_event_points_awarded_after" : [] },
    "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" : { "NOT data_is" : { "data" : [ "total-points" ], "op" : "\u003C", "value" : "7" } },
            "DO" : [
              { "add_badge_by_name" : { "badge" : "1", "user" : [ "userpoints-transaction:user" ] } }
            ]
          }
        ]
      }
    ]
  }
}

It does retrieve, as the very first Rules Action (not Rules Condition!) the current amount of user points of a user. If the amount is at least 7, it will grant the user badge.

The key difference here is that you do not need custom PHP code (in your Rules Condition) to get this to work (and you don't need to enable the PHP filter for this ...). In this example I'm using 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 (for more details on that, refer to the answer to "What's the alternative to using the Conditional Rules module?").

However, by using this module, you can consolidate the logic for various user badges in a single rule, e.g bronze for 7 points, silver for 77 points, gold for 777 points.

The clue to make this rule work is the very first Rules Action "Load user points of a user". That's the alternative (work around?) for something like a missing Rules Condition to "check the current user points for a user".

Remove a new badge

If you want "a user's old badge to be replaced by a new one" (as in your question), then you should also add a 2nd Rules Action to the rule shown above. The action to be used is remove_badge_by_name (instead of add_badge_by_name).

Only grant a new badge once

To avoid "displaying a message each time when user getting more than 7 user points" (as in your question), just add a Rules Condition like "NOT User has badge". This is one of the Rules Conditions provided by the User badges module.

Display the badge

To actually "display the badge with the username at the top" (as in your question also), you could use what's written in the Community Documentation about User Badges, i.e:

To display user badges in your theme use:

<?php
  if (module_exists('user_badges')) {
    print user_badges_for_uid($uid);
  }
?>

Note: $uid means 'a user id' here, not the literal use of $uid. Most people will use the uid of the node ($node->uid) or comment ($comment->uid) author.

In Drupal (and theming), $node is a PHP object that represents the node, and $comment represents the comment. They are not always both available in every template file, so check the comments at the top of the file to see what is available. You may have access to other uids (user ids), and in these cases you can replace $uid with that value.

0

First of all, add the badge(s) you'd like to use at Configuration > People > Badges > Add new badge. Afterwards, create a rule for every badge, similar to the following one:

{ "rules_new_badge" : {
    "LABEL" : "Add new badge",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "php", "rules", "user_badges", "userpoints_rules" ],
    "ON" : { "userpoints_event_points_awarded_after" : [] },
    "IF" : [
      { "php_eval" : { "code" : "$current_points = userpoints_get_current_points($userpoints_transaction-\u003Euid, \u0027all\u0027);\r\nif ($current_points \u003E=7) {\r\n  return true;\r\n}" } }
    ],
    "DO" : [
      { "add_badge_by_name" : { "badge" : "1", "user" : [ "userpoints-transaction:user" ] } }
    ]
  }
}

Import it and modify it, according to your needs. To delete a badge, you can add another Rule with the action 'Remove badge by name'. Mind that I used a PHP Evaluation condition in order to use your PHP code in the Rule. I would, however, advise against this and use the Conditional Rules module instead.

Displaying the user badges next to the user names can be achieved by theming the comments in the comments.tpl.php file. This answer might help.

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.