Using Rules Components in Drupal 7: Even for Beginners!
One Rules feature I always shied away from was Components. After installing Rules and heading to the admin page to set up a new rule, I'd always notice the Components tab and assume this was for experts only, for those who had adequately suffered through its arcane-looking UI.
Understanding the Rules module itself is not that difficult; it is simply an action-reaction module; in other words, "Upon this action (e.g. user logs in), evaluate some condition (e.g. the user's role) and then perform some reaction (e.g. display a custom welcome message)". Right, easy enough, but what are components for, and when you enter the Components UI, what are "parameters" and why do you need them? And when does a Rules Component execute anyway? What's the use of the various component types: Rules, Rule Sets, Condition Sets, and Action Sets?
Let me break it down.
Condition Sets and Action Sets
These refer to reusable bits of functionality that may be needed in several areas. Imagine, for instance, that you have a number of different rules that need to execute a sequence in which a page redirect happens, a message is shown, and then an email is sent to the user. For some reason. Well, you could add each of those as a separate Rules action for each rule that needed it... or you could create an "action set" that combined each of these. From then on, you can edit a "regular" rule and, when adding actions to that rule, look under the "Components" heading (within the <select> menu of available actions) to "call" that action set.
The same is true with condition set; if you want to evaluate a set group of conditions, and then call all of them at once, easily, do the same thing (except, of course, you'll add this condition set when adding conditions to your rule).
Rules and Rule Sets
Using Rules, have you ever needed a stepwise procedure in which you first needed to evaluate conditions, then load some data or an entity, and then perform further conditions followed by yet more actions?
Let me give an example: imagine you have a Drupal Commerce store. Upon certain types of orders, during the checkout process you need to loop, or iterate, over each product in the cart (Drupal Commerce calls them Line Items), then evaluate further conditions about each line item in the order. Without Rules Components, you can't do that. You can find each line item in the cart and perform a simple action—but not something complex. Here is where we get into the Rule and Rule Set type of component. Here's how you'd work.
Rules Event: After updating an existing Commerce order
Condition: Order is "in checkout" (hint: use "data comparison" for this)
Action: Loop over each line item in the cart. This will load the line item entity for each one.
Now that you've created the simple rule, jump over to the scary Components tab. Create a rule. You'll notice the first thing it's asking for are "parameters". What the heck? Well, essentially, silly me, these are just variables that can be passed into this subroutine or function. If we're talking about line items, the "Data Type" will be Commerce Line Item Entity (under the "Entity" section in the <select> menu). Since we're iterating over all line items in an order within the parent rule, what this lets us do is create a new rule that gets the full data object of each full line item entity, in turn, for every iteration of the loop. We can then perform functions on each line item—such as edit a field on the line item if it contains a particular product, for instance. (Since Commerce Line Items are bundle-able and fieldable entities, you can add any custom field you want to it, representing, say, a discount or even user-fillable field—for example, for customizable products). You can add any other parameter too: for instance, you may want to pass in the Commerce Order object itself in case you need information from that.
Creating rule sets are similar, except that you can add multiple rules that execute all at once.
Now, how do you "call" this component? Unlike traditional rules, it has no event associated. Here's how: you re-enter your "parent" rule and, in the Actions section, navigate to the "Components" heading in the <select> menu and find the component you created. Once you do that, Rules will ask you to provide values for the parameters the component is asking for. If you used a Commerce Line Item Entity as your parameter, it'll ask, essentially, "which line item will you be passing to this component?" If you're calling this component from within a loop, you probably need to pass it the value of the "current_line_item" or similar variable name you set up to represent each iteration of the loop. Now, when Rules loops over your line items, it'll call your component, say, 5 times for an orde with 5 line items in it.
That's the basic idea. I hope this helps some folks!