I'm sure this is a common request, but I haven't been able to figure it out.

I want to check through a list to see if a condition has been met, and then take an action as a result.

The intuitive way to do it would be to have the condition section support looping, and then we could put any kind of component in the condition loop, but that's not there.

Given that it's missing... How can it be done? Loop in the actions section, have the component return a TRUE if something is supposed to be true and then supply that returned value to another component as a parameter?

I note this comment which I think is asking the same question.

The actual situation:

I want to see if a Commerce order contains a given line item type. I want to take an action if it does.

Thanks for any help.

Comments

Itangalo’s picture

Hya

The approach you describe – looping through the list and calling a component – is the one to use for the general case. This isn't very handy, and it would be quite nice to have some kind of loop in the condition section.

However, in your particular case there is a much quicker solution: the "list contains item" condition. This assumes that you have the ID for the relevant line item available, which isn't necessarily the case if there are several items you want to compare against.

If I was faced with this problem, I would probably write a custom condition. These are quite easy and quite fun to write. And then I would start thinking about how to create a general loop plugin for conditions. These are difficult.

EDIT: I just realized another approach. Rules Bonus Pack has a condition called "check number of results in a view". If you can create a view that lists the line items of the selected type, for this user, then you can use Rules to check if that view has at least one row. That would mean loading another view, which has some performance implications. And it would mean using Rules Bonus Pack, which is in dev and explicitly says that it can change things with little warning.

twistor’s picture

So here's my stab at it:

First add a Rule component, this will be executed once per iteration.
Then, create your normal rule with a loop that executes the component created above.

Per the example:
Create a rule component that checks if a single line item matches your criteria and execute the appropriate action.
** When describing the variables for the component, the line item will be a parameter.
Create the normal rule that loops over the line items, then add a loop action that executes the above component.

I think this might be what Itangalo was referring to in his first answer, but maybe I spelled it out better. Probably not.

rfay’s picture

I want to check each line item for a *type*.

foreach line item  # in main rule (unfortunately in action section)
   If the line item is of a particular type (not SKU)
     let the main rule take an action (return true? Return a provided value? What would I do then?

What *does* work is quite ugly, it's @twistor's approach, have the component take the action. That means the action may be taken many times in a given situation. It's what I actually did for the problem at hand.

And yes, a custom condition is an option here and moves the problem forward. But there's actually no reason for that given that rules should be expressive enough without custom code.

@Itangalo thanks for the rules bonus pack approach.

Do you know if we already have a feature request for a loop (or component that returns a true/false) in the conditions section of a rule?

This kind of poverty of expression is probably the weakest point of rules.

twistor’s picture

You can make a component return a truth value. You just have to add a variable that's "provided" by the component. Then you can set it in an action. This will return it to the outer scope.

The problem is that to check the return value, you need a new component.

Itangalo’s picture

@rfay: I know there has been discussions of allowing conditions inside actions, but I don't think I've seen any issue on loops within conditions. I agree that it would be a valuable addition to Rules. This should definitely be possible to do.

rfay’s picture

Status: Active » Closed (duplicate)

I opened #1382022: Allow components as conditions; marking this as a duplicate.

Thanks for the help on this!

Itangalo’s picture

Good one!

mitchell’s picture

Issue tags: +lists and loops

tagging