We can emulate a for loop by an action "create a counter array" like this pseudocode:

list=counter-array(number)
foreach(list) do stuff

where counter-array(5) == {0,1,2,3,4}

See: #1525596: [Meta] Rules loops extended

Related: #1301022: Action: type conversion for numbers, integers, and strings

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

geek-merlin’s picture

@fago: what do you think about a patch directly rolled from #1329904-11: Loops: while and tail recursion support?

geek-merlin’s picture

Issue summary: View changes

add related

geek-merlin’s picture

Issue summary: View changes

added meta

geek-merlin’s picture

Status: Active » Needs review
FileSize
2.95 KB

banzai! herre's the patch, with test that passes on my box.

mitchell’s picture

Assigned: Unassigned » fago
mitchell’s picture

Priority: Major » Normal
Status: Needs work » Needs review
Issue tags: -lists and loops

[edit] next comment has more useful info

mitchell’s picture

Title: Action: create counter array » Action: generate a list from an integer
Priority: Normal » Major
Status: Needs review » Needs work
Issue tags: +lists and loops

There are three different versions of this for loops implementation (not including the Views based ones in Rules Bonus Pack and VBO): this, #1329904-11: Loops: while and tail recursion support, and Rules Array Create, that all have practically the same exact code.

This implementation is actually a patch with a test (props axel.rutz!), so the only part remaining is finding a suitable name for the action. Here are four different names to choose from (in no particular order):

  • Create counter array
  • Generate a list from an integer
  • Turn integer into list
  • Create an array

For future reference, my personal opinion is that this should simply be put in 'Calculate a value' as the multiplication of an integer by a NULL value. I outlined this here: #1540634: Calculate a value: support strings, lists, & files.

geek-merlin’s picture

Priority: Normal » Major
Issue tags: +lists and loops

#5: i see the beauty of said approach, and as a mathematician i like it.
i'm not so sure if everyone can appreciate and understand that beauty.

so it's up to fago to point an architectural direction.

klausi’s picture

Status: Needs review » Needs work
+++ b/modules/data.rules.inc
@@ -163,6 +163,23 @@ function rules_data_action_info() {
+  $return['integer_to_list'] = array(
+		'label' => t('Turn integer into list'),
+    'parameter' => array(

indentation error. Also, this needs some description to explain what is happening here.

+++ b/modules/data.rules.inc
@@ -163,6 +163,23 @@ function rules_data_action_info() {
+        'type' => 'integer',
+        'label' => t('Integer')

comma is missing on the last array element, see http://drupal.org/coding-standards#array

+++ b/modules/data.rules.inc
@@ -163,6 +163,23 @@ function rules_data_action_info() {
+    'group' => t('Data'),
+		'base' => 'rules_action_integer_to_list',
+  );

indentation error

+++ b/tests/rules.test
@@ -1412,6 +1412,15 @@ class RulesIntegrationTestCase extends DrupalWebTestCase {
+    // Test Action: Integer to list.
+    $action_set = rules_action_set(array('integer' => array('type' => 'integer', 'label' => 'Integer'), 'list' => array('type' => 'list<integer>', 'label' => 'List')), array('integer', 'list'));

please break that line up for readability.

But otherwise I think such an action would make sense. Personally I like the name "Generate a list from an integer" best.

mesch’s picture

My original action function can be reduced from 5 to 1 lines of code by using the "range" function as follows:

function rules_action_integer_to_list($integer) {
  return array('converted_list' => range(1, $integer));
}
mitchell’s picture

Component: Rules Engine » Rules Core
Assigned: fago » Unassigned

Status?

kenyan’s picture

This works perfectly.
I really wish I'd seen this patch before chasing my tail trying to write the loop in php.
Use case (If no one minds).

I have a field collection that holds 3 fields (multiple collection):
1) full names
2) email
3) number of invites (integer)

Additionaly I have an event content type.

When a user creates an event, he sends invites using signup to an email list with rules handling the html emails.
Rules then sends the user to the content type the field collection is attached to.
Here, the user then fills out a friends who he can send a certain number of invites to 'share' with friends (number of invites).
I use rules to create a new node of a content type called shared invites. A new node is created for each of 'number of invites'.

This patch has of course made this oh so easy for me to convert the integer into a list which I can then loop through to create the invites for each friend to share.
All I can say is, thanks for the patch big time.

geek-merlin’s picture

Status: Needs work » Needs review
FileSize
3.03 KB

here's #2 re-rolled with all the valuable input from #7 and #8.

Please review so we can finally get this in.

Status: Needs review » Needs work

The last submitted patch, 0001-implemented-1525582-by-MEsch-axel.rutz-klausi-implem.patch, failed testing.

geek-merlin’s picture

geek-merlin’s picture

Status: Needs work » Needs review
geek-merlin’s picture

Issue summary: View changes

moved related

JuliaKoelsch’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

I ran into an issue trying to use the Role Reference value in a Rule action because the role reference field provides an integer, not a list (https://drupal.org/node/1617880). I applied the patch in #13, added an action to create a list from the field value, and then was able to use the value. In other words, the patch works for me.

I feel a bit presumptuous changing the status because I don't know that anyone else but me and testbot have tested it, but it looks like it was code reviewed above and requested changes were made. So, changing to RTBC in hope that this gets into the next release. But feel free to change back if I jumped the gun. Thanks!

fago’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/modules/data.rules.inc
@@ -163,6 +163,25 @@ function rules_data_action_info() {
+    'label' => t('Generate a list from an integer'),

Code looks good, but I think the description and label is confusing and does not tell you what it does. What kind of list does it create? What's in there?
Also, would it make sense to have similar options as php's range() function has?

eileenmcnaughton’s picture

hmm - this seems to be hung up for a long time on agreeing a label. I guess it creates a list of integers up to the value of the integer. But, I think I'll just create a little custom module that implements it as the code seems to be on this thread to do that

eileenmcnaughton’s picture

here it is as a mini-module if this helps anyone

https://github.com/eileenmcnaughton/rules_convert_list