6

I want to create a node based on a webform data using the Rules module. This is because of a complication surrounding relationships within the associated CRM system.

I am already at the point where I have the webform created and have got to the following (and working) point within Rules:

{ "rules_member_news_import_" : {
"LABEL" : "Member News (cloned)",
"PLUGIN" : "reaction rule",
"OWNER" : "rules",
"REQUIRES" : [ "webform_rules", "rules" ],
"ON" : { "webform_rules_submit" : [] },
"IF" : [
  { "webform_has_id" : {
      "form_id" : [ "form_id" ],
      "selected_webform" : { "value" : { "webform-client-form-730" : "webform-client-form-730" } }
    }
  }
],
"DO" : [
  { "entity_create" : {
      "USING" : {
        "type" : "node",
        "param_type" : "newsfrommembers",
        "param_title" : "[data:title_member_news-value-raw]",
        "param_author" : [ "user" ]
      },
      "PROVIDE" : { "entity_created" : { "entity_created" : "Created entity" } }
    }
  }
]

What I need to do is use the rest of the fields in the webform to transpose the information across, for example the body text and an image.

What I am trying to learn is how to also incorporate the body and other information. I used the export to add what I thought would work, for example:

"param_body" : "[data:body]"

within the entity_create action, however when I imported the edited text it simply disappeared, so I am assuming that I have to add a separate action to add entity variables.

I went back to using the menus and I again could not get it to work. I must be doing something basic wrong.

1 Answer 1

4

1st attempt

Before using a Rules Action like "Set a data value" for your a field, you have to make sure to add a Rules condition Entity has field (related to the field for which you want to set a value). And make sure to add that Entity has field condition BEFORE other Rules Conditions in which you might want to refer to this field.

That's also what is mentioned in the Rules UI, e.g. when you're adding a "data comparison" condition: somewhere it says "The data selector helps you drill down into the data available to Rules. To make entity fields appear in the data selector, you may have to use the condition 'entity has field' (or 'content is of type')".

The above applies to any of your "... rest of the fields in the webform" (as in your question).

For a video tutorial that illustrates the importance of this Entity has field condition, refer to Data types and data selection, especially what is shown between about 13:30 and 17:30 in it.

2nd attempt

The prior attempt is more or less like a Getting-started-with-Rules that resolves various situations where some variables appear to not be available in Rules Actions, etc. However, for this specific question, which is about using Rules in combination with Webform, things are a very little bit more complicated, as further explained below.

Let's assume I have a webform created with some of its fields with machine names like so:

  • contact_us_first_name.
  • contact_us_last_name.
  • contact_us_subject.

After you add these fields (with identical machine names) to any of your own forms, you should be able to import the prototype-rule below (using the Rules UI) in your own environment (without running into an integrity constraint):

{ "rules_create_a_node_from_a_submitted_webform" : {
    "LABEL" : "Create a node from a submitted webform",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "webform_rules" ],
    "ON" : { "webform_rules_submit" : [] },
    "IF" : [
      { "user_has_role" : { "account" : [ "user" ], "roles" : { "value" : { "2" : "2" } } } }
    ],
    "DO" : [
      { "drupal_message" : { "message" : "The webform component submitted by [data:contact_us_first_name-value] (= [data:contact_us_first_name-title]) [data:contact_us_last_name-value] (= [data:contact_us_last_name-title]) contains a field labeled \u0022[data:contact_us_subject-title]\u0022 which has value \u0022[data:contact_us_subject-value]\u0022." } }
    ]
  }
}

In the above rule I included an extra Rules Condition to prevent the Rules Action from being executed for anonymous users (feel free to adapt the role id of it, or just remove that Rules Condition. And the rule is triggered via Rules Event "After a webform has been submitted".

The Rules Action only displays an (informational) message on the site (my recommended way of writing and debugging Rules ...) after a webform gets submitted. Here is what I specified (in the rules UI) as the message to be shown:

The webform component submitted by [data:contact_us_first_name-value] (= [data:contact_us_first_name-title]) [data:contact_us_last_name-value] (= [data:contact_us_last_name-title]) contains a field labeled "[data:contact_us_subject-title]" which has value "[data:contact_us_subject-value]".

Here is a sample of the message shown in my own setup:

The webform component submitted by Dries (= First name:) Buytaert (= Last name:) contains a field labeled "Subject:" which has value " Rumour goes that the rules module can even replace the node_convert module! ".

What the above prototype-rule shows is that the "clue" to answer your question is that you have access to all labels and all values of any field of a webform available, ie:

  • [data:MachineFieldName-title] contains the Label of a field with machine name MachineFieldName.
  • [data:MachineFieldName-value] contains the Value of a field with machine name MachineFieldName

3rd attempt

The above is a good start, but still not sufficient to achieve your goal (= "... use the rest of the fields in the webform to transpose the information across, for example the body text ...", as in your question). However, you can use a technique similar to what is described in my answer to "How to do a data comparison to submitted webform data when using the Rules module?". For short:

  • Add an extra Rules Action to Add a variable (for each of the Webform components to transpose the information across, with a value assigned to it equal to your [data:ComponentName-value-raw] (and with a data type which equals the data type of your Webform component).
  • In your subsequent Rules Actions you can refer to the value of these variables you just added (that's the clue!).

Demo

Webform components

Assume a webform with form_id=191 and with these Webform Components:

  • Label = Title, Machine name = demoform_title, Data type = Textfield.
  • Label = Text, Machine name = demoform_text, Data type = Textarea.
  • Label = Number, Machine name = demoform_number, Data type = Number.
  • Label = Option, Machine name = demoform_option, Data type = Select options (single value).

Article content type

Assume an Article content type with these fields:

  • Label = Title, Machine name = title, Field type = Node module element.
  • Label = Body, Machine name = body, Field type = Long text and summary.
  • Label = Free Format Nr, Machine name = field_free_format_nr, Field type = Integer.
  • Label = OptionList, Machine name = field_optionlist, Field type = List(text).

Custom Rule

Here is a custom rule (in Rules export format), which is an extended (improved) version of the rule included in the question. This rule will create a new node (of type Article), and which will use the data included in the above mentioned Webform components:

{ "rules_create_a_node_from_webform_data" : {
    "LABEL" : "Create a node from webform data",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "webform_rules", "rules" ],
    "ON" : { "webform_rules_submit" : [] },
    "IF" : [
      { "webform_has_id" : {
          "form_id" : [ "form_id" ],
          "selected_webform" : { "value" : { "webform-client-form-191" : "webform-client-form-191" } }
        }
      }
    ],
    "DO" : [
      { "drupal_message" : { "message" : "The webform submitted contains these fields:\r\n\u003C\/ul\u003E\r\n\u003Cli\u003Ethe field labeled \u0022[data:demoform_title-title]\u0022 which has value \u0022[data:demoform_title-value-raw]\u0022.\u003C\/li\u003E\r\n\u003Cli\u003E the field labeled \u0022[data:demoform_text-title]\u0022 which has value \u0022[data:demoform_text-value-raw]\u0022.\u003C\/li\u003E\r\n\u003Cli\u003E the field labeled \u0022[data:demoform_number-title]\u0022 which has value \u0022[data:demoform_number-value-raw]\u0022.\u003C\/li\u003E\r\n\u003Cli\u003E the field labeled \u0022[data:demoform_option-title]\u0022 which has value \u0022[data:demoform_option-value-raw]\u0022.\u003C\/li\u003E\r\n\u003C\/ul\u003E" } },
      { "variable_add" : {
          "USING" : { "type" : "text", "value" : "[data:demoform_text-value-raw]" },
          "PROVIDE" : { "variable_added" : { "var_demoform_text" : "Form variable text" } }
        }
      },
      { "variable_add" : {
          "USING" : { "type" : "text", "value" : "[data:demoform_number-value-raw]" },
          "PROVIDE" : { "variable_added" : { "var_demoform_number_text" : "Form variable number text" } }
        }
      },
      { "data_convert" : {
          "USING" : { "type" : "integer", "value" : [ "var-demoform-number-text" ] },
          "PROVIDE" : { "conversion_result" : { "var_demoformvar_number" : "Form variable number" } }
        }
      },
      { "variable_add" : {
          "USING" : { "type" : "text", "value" : "[data:demoform_option-value-raw]" },
          "PROVIDE" : { "variable_added" : { "var_demoform_option" : " Form variable option" } }
        }
      },
      { "entity_create" : {
          "USING" : {
            "type" : "node",
            "param_type" : "article",
            "param_title" : "[data:demoform_title-value-raw]",
            "param_author" : [ "user" ]
          },
          "PROVIDE" : { "entity_created" : { "article_created" : "Created article" } }
        }
      },
      { "data_set" : {
          "data" : [ "article-created:body:value" ],
          "value" : [ "var-demoform-text" ]
        }
      },
      { "data_set" : {
          "data" : [ "article-created:field-free-format-nr" ],
          "value" : [ "var-demoformvar-number" ]
        }
      },
      { "data_set" : {
          "data" : [ "article-created:field-optionlist" ],
          "value" : [ "var-demoform-option" ]
        }
      },
      { "data_set" : { "data" : [ "article-created:comment" ], "value" : "0" } },
      { "entity_save" : { "data" : [ "article-created" ], "immediate" : "1" } },
      { "drupal_message" : { "message" : "A new article got created, with nid=[article-created:nid] and url=[article-created:url]" } }
    ]
  }
}

Some more details about the Rules Actions that were added:

  • Show a message on the site: This is just for debugging/demo purposes (remove it you don't want/need it anymore). Here is a sample message that gets displayed after submitting a webform:

    The webform submitted contains these fields:

    • the field labeled "Title" which has value "Some interesting title of my webform".
    • the field labeled "Text" which has value "Just some text, with some additional text and yet another line and another one".
    • the field labeled "Number" which has value "842316".
    • the field labeled "Option" which has value "A".
  • Add a variable (twice): To make the value of the Webform components demoform_number and demoform_option available in subsequent Rules Actions. Note that for demoform_number an additional Rules Action Convert data type is needed to get it to work.

  • Set a data value (3 times): To populate the node's body and the 2 node fields, using the variables created in a preceeding Rules Action.

  • Set a data value: To set "Comments closed" for the node being created (this is an optional Rules Action, just an illustration of other things you can do with such node being created).

  • Save entity: To actually save the node.

  • Show a message on the site: This is just for debugging/demo purposes (remove it you don't want/need it anymore). Here is a sample message that gets displayed after submitting a webform:

    A new article got created, with nid=123 and url=http://www.example.com/node/123

Final result

After submitting the webform with data as in the sample above, a new article (with node id = 123) got created, and with these details about that node:

  • Title: Some interesting title of my webform
  • Body:

    Just some text,

    with some additional text

    and yet another line

    and another one

  • Free Format Nr: 842316

  • OptionList: Advanced (the label corresponding to key-value "A")

Additional possibilities

With some further refinements, the above prototype-rule can also be used to create a Rules based alternative for the Node Convert module ... and seems to have the potential also to create like an Entity Convert equivalent also.

5
  • I have used Entity has field to expose the fields that are in the content type for Create a new entity however I can not get it to set a data value equivalent to the value of one of the fields in the submitted webform. I had originally made the mistake of setting the webform field key to be body rather than something unique. I am now going to try and work out how I expose that webform data as [data:...] does not seem to expose the fields. May 3, 2016 at 7:50
  • To clarify further I have also tried using webform-data:... which was not recognised and selected-webform:... which had no further drilldown May 3, 2016 at 8:48
  • Unfortunately the occasional chance I get to experiment has not come up with any solution. I suspect one significant problem is that one of the field keys is restricted as it is a CiviCRM specific contact reference. May 30, 2016 at 9:29
  • @DarrenWhittenham-Gray : this was tooooo chalenging to not extend my answer with a "3rd attempt" of it (and include a demo of a working example). Dec 4, 2017 at 12:16
  • Hi Pierre. Thank you for your most recent contribution and I am sure that it is going to help someone. Unfortunately I am no longer a volunteer at the organisation that was working with Drupal and Civi. Thank you for all your assistance over the last two years though. Dec 10, 2017 at 10:49

Your Answer

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

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