1

I'm using the Rules module and I would like to make a rule to check wheter a new element has been added to a list in a node.

First I have tried "List Count comparison" but it can only compare a list to an integer, then I have tried with a custom php code condition but I have troubles with getting the right data. i don't understand if i'm missing something and there is a simple way or it can be done only with custom php code (in which case i'd like to know how to correctly do it, it's worth telling that the list is an entity reference)

This is the PHP code i have tried. The event is "After the update of an existing content of type Q&A", so I have $node and $node_unchanged available. The field is called field_lista_gestori and contains a list of users.

$gestoriCount=count($node->field_lista_gestori)>count($node_unchanged->field_lista_gestori);
return $gestoriCount;

But then I have discovered that field_lista_gestori just contains a number (which I think is the reference ID) and I haven't made any other attempts after this.

1
  • 1
    to get a better answer, post the code you have tried, as well as information relating to field names. This will allow us to evaluate the problem better
    – Geoff
    Commented Jul 13, 2014 at 16:32

2 Answers 2

1

You're counting the wrong thing...item data is a bit further down the rabbit hole (inside the language array):

$count_new = count($node->field_lista_gestori[$node->language]);
$count_orig = count($node_unchanged->field_lista_gestori[$node->language]);
6
  • In the logs i get this error: "Notice: Undefined index: it in eval() (line 5 di /home/lineamicadev/sito/sites/all/modules/rules/modules/php.eval.inc(146) : eval()'d code)." "it" is the language (italian)
    – valepu
    Commented Jul 13, 2014 at 17:59
  • You just need to find out what the right language code both nodes is, and replace both instances of $node->language above with the appropriate string
    – Clive
    Commented Jul 13, 2014 at 18:10
  • If i go on the content page, it says the language for the node i tested the rule on is "Italian". I don't know if this changes things but as i said in the question the field is made as an "entity reference" (using the "entity reference" module)
    – valepu
    Commented Jul 13, 2014 at 18:16
  • 1
    doing some "print_r" i managed to find the parameter to get to the data. It's "und" which i guess means "undefined", probably the entity references are language independent so even though the node language is italian, they use "und" as field.
    – valepu
    Commented Jul 13, 2014 at 19:04
  • 1
    It does indeed, you can use the LANGUAGE_NONE constant to refer it so you don't have magic vars in your code
    – Clive
    Commented Jul 13, 2014 at 19:13
0

Sure you can do this "without custom code" (and more important: without the need to enable the dangerous PHP filter ...). Read on for more details about how to get this to work ... and not only to discover new items added to the list (as in your question), but also to discover items removed from the list.

To process a multi-value field with Rules, I think you should use a completed different approach, which is related to the Rules Condition "List contains item" (and the negations of it).

Have a look at this rules example (in Rules export format), which processes a multi-value field also, in my case it is a list of eMail Ids (replace "eMail ID" by whatever matches your case):

{ "rules_verify_updates_to_selected_email_ids" : {
    "LABEL" : "Verify updates to selected eMail IDs",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules_conditional", "rules" ],
    "ON" : { "node_update--article" : { "bundle" : "article" } },
    "DO" : [
      { "LOOP" : {
          "USING" : { "list" : [ "node-unchanged:field-email-addresses" ] },
          "ITEM" : { "previous_email_id" : "Previous eMail ID" },
          "DO" : [
            { "CONDITIONAL" : [
                {
                  "IF" : { "NOT list_contains" : {
                      "list" : [ "node:field-email-addresses" ],
                      "item" : [ "previous-email-id" ]
                    }
                  },
                  "DO" : [
                    { "drupal_message" : { "message" : "Value [previous-email-id:value] was removed from the multi value field." } }
                  ]
                }
              ]
            }
          ]
        }
      },
      { "LOOP" : {
          "USING" : { "list" : [ "node:field-email-addresses" ] },
          "ITEM" : { "current_email_id" : "Current eMail ID" },
          "DO" : [
            { "CONDITIONAL" : [
                {
                  "IF" : { "NOT list_contains" : {
                      "list" : [ "node-unchanged:field-email-addresses" ],
                      "item" : [ "current-email-id" ]
                    }
                  },
                  "DO" : [
                    { "drupal_message" : { "message" : "Value [current-email-id:value] was added to the multi value field." } }
                  ]
                }
              ]
            }
          ]
        }
      }
    ]
  }
}

If you just replace the machine name "field-email-addresses" by the machine name of your field (prior to import), you should be able to experiment with this rule in your own site to see it at work (for nodes of content type "Article", adapt this type to fit your needs).

Here is a sample of the messages I get when I update an article, and while doing so I add 1 more eMail ID and at the same time I remove an existing eMail Id:

Value [email protected] was removed from the multi value field.
Value [email protected] was added to the multi value field.

So the clue to make this work is:

  1. first iterate over all field values of your field of the unchanged node (to find the removed values).
  2. then also iterate over all field values of your field of the changed node (to find the inserted values).

Note: As an alternative to using the Conditional Rules module (which is required for this rule to work), you can also rework the relevant part of my Rules example into performing equivalent Rules Component. For more details on using Rules Components instead of Conditional Rules, refer to the answer to "What's the alternative to using the Conditional Rules module?".

PS: I'm assuming this question is about D7.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.