Problem/Motivation

I am attempting to send an email to a user that is specified by a reference field on the node in the user's preferred language. When I use data selection mode to select: node.field_my_userref.entity.preferred_langcode.language (object) I get the following error:
Expected a language data type for context Language but got a language_reference data type instead.

Steps to reproduce

1. Create a content-type
2. Add an entity reference -> user field called field_my_userref
3. Add a new reaction rule on content update
4. Add an action Send email

Parameters: to: [node.field_my_userref.entity.mail.value], subject: My subject, message: My email body, reply: '', language: node.field_my_userref.entity.preferred_langcode.language (object)

5. Hit save and error should appear.

Proposed resolution

Not sure, happy to provide a patch if someone can point me in the right direction.

Remaining tasks

User interface changes

API changes

Data model changes

Issue fork rules-3263463

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

joel_osc created an issue. See original summary.

joel_osc’s picture

Issue summary: View changes
tr’s picture

This seems to be a problem where you're passing a reference to a language object instead of a language object. That situation (reference instead of entity) is the subject of #3059402: Set data action in referenced entity.. You can try out the patch there to see if it fixes the problem for you.

In the future, please export your Rule and post it, rather than trying to describe how you configured the Rule. The export gives me all the information, while a description is always missing important information. But from your description, I think you entered [node.field_my_userref.entity.mail.value] as the "To:" address, which is not valid. A good strategy when debugging is to print out the values in a "Show a message" action to see if the values you entered really have the values you expect them to have.

joel_osc’s picture

Hi @TR, thank-you for the quick reply - I will take a look at the issue you have referenced and see if I can get my rule working. Your help is much appreciated!

Sorry, about not including the rule - for reference here it is, thanks for finding the issue with the email address. It looked like it was working because I was debugging with email redirect on for testing. :(

uuid: f9c8572e-5171-4a7f-bf17-981c114992ea
langcode: en
status: true
dependencies: {  }
id: record_set_to_mgr_initial_review
label: 'Record set to Manager initial review'
events:
  -
    event_name: 'rules_entity_update:node--record'
description: 'Email the manager to let them know the record requires review.'
tags: {  }
config_version: '3'
expression:
  id: rules_rule
  uuid: 636bdbd4-2b72-4d69-b6f4-0f48caf4be7d
  weight: 0
  conditions:
    id: rules_and
    uuid: 35e568cc-d52e-46ce-8260-959f3bce9ba2
    weight: 0
    conditions:
      -
        id: rules_condition
        uuid: 34f40ae9-0bd4-4f67-ab9b-e4033f42cb95
        weight: 0
        context_values:
          type: node
          bundle: record
        context_mapping:
          entity: node
        context_processors:
          type:
            rules_tokens: {  }
          bundle:
            rules_tokens: {  }
        provides_mapping: {  }
        condition_id: rules_entity_is_of_bundle
        negate: false
      -
        id: rules_condition
        uuid: 956d2b02-3fc3-4143-91c6-3c727300baba
        weight: 0
        context_values:
          operation: '=='
          value: publication_approval_initial_manager_review
        context_mapping:
          data: node.field_workflow_state.value
        context_processors:
          operation:
            rules_tokens: {  }
          value:
            rules_tokens: {  }
        provides_mapping: {  }
        condition_id: rules_data_comparison
        negate: false
      -
        id: rules_condition
        uuid: a9f56497-ee1b-4aac-8800-7c98a9183015
        weight: 0
        context_values:
          type: node
          bundle: record
        context_mapping:
          entity: node_unchanged
        context_processors:
          type:
            rules_tokens: {  }
          bundle:
            rules_tokens: {  }
        provides_mapping: {  }
        condition_id: rules_entity_is_of_bundle
        negate: false
      -
        id: rules_condition
        uuid: 987df9c9-3f63-415f-9eed-4b7c843fa30e
        weight: 0
        context_values:
          operation: '=='
          value: publication_approval_initial_manager_review
        context_mapping:
          data: node_unchanged.field_workflow_state.value
        context_processors:
          operation:
            rules_tokens: {  }
          value:
            rules_tokens: {  }
        provides_mapping: {  }
        condition_id: rules_data_comparison
        negate: true
  actions:
    id: rules_action_set
    uuid: ebd2109c-4556-4a25-875e-add7a4302d30
    weight: 0
    actions:
      -
        id: rules_action
        uuid: 4770509b-22c1-4b7e-ab8d-31448e67e9a4
        weight: -50
        context_values:
          token: '[site:url]/user'
          token_entity: ''
        context_mapping: {  }
        context_processors:
          token:
            rules_tokens: {  }
          token_entity:
            rules_tokens: {  }
        provides_mapping:
          token_value: site_url
        action_id: rules_token_get_token_value
      -
        id: rules_action
        uuid: 3f5937cc-9f0c-459d-a937-54d14955b002
        weight: -48
        context_values:
          subject: 'A publication request is ready for your review (Manager initial review)'
          message: 'Please go to <a href="{{ site_url }}">your dashboard</a> to review: <strong>{{ node.title.value }}</strong>. '
          reply: ''
          language: node.field_mgr_approver.entity.preferred_langcode.language
        context_mapping:
          to: node.field_mgr_approver.entity.mail
        context_processors:
          subject:
            rules_tokens: {  }
          message:
            rules_tokens: {  }
          reply:
            rules_tokens: {  }
          language:
            rules_tokens: {  }
        provides_mapping: {  }
        action_id: rules_send_email
      -
        id: rules_action
        uuid: 6b4e3c1a-aa18-4324-8298-817593253db3
        weight: 0
        context_values:
          message: 'Your request for review has been submitted, thank-you!'
          type: status
          repeat: false
        context_mapping: {  }
        context_processors:
          message:
            rules_tokens: {  }
          type:
            rules_tokens: {  }
          repeat:
            rules_tokens: {  }
        provides_mapping: {  }
        action_id: rules_system_message

We really appreciate all the work you maintainers are doing on this incredibly important module. Cheers.

joel_osc’s picture

I tried it with the patch and I still got the same error:

Expected a language data type for context Language but got a language_reference data type instead.

I am not sure how to either load a language object from a langcode or convert the existing language_reference data type to a language data type in Rules without writing a custom action. Any suggestions are appreciated.

jonathan1055’s picture

Hi joel_osc,
Yes you are right, there is a problem specifying a language via selection. I've done some investigating and cannot make it work for any of the actions or conditions that need a language.
Selecting @user.current_user_context:current_user.preferred_langcode gives "Expected a language type ... but got a list data type instead."
preferred_langcode.language gives "... but got a language_reference data type instead."
preferred_langcode.value gives " ... but got a string data type instead."

I was aware of this via my testing on #2471481: Integrate Typed Data Widgets and had been trying to solve it there, but now it seems it would be better to fix it separately to that issue.

joel_osc’s picture

Hi Jonathon1055, thank-you for confirming! One option I can think of for a solution would be to change the param to accept a string (langcode) instead of a language object, since this is all it uses anyway, but I am afraid that might be a bit hackish. I was concerned about backwards compatibility, but now that you have confirmed the issue I don't think anyone can actually have a rule that uses the language option. So then the only issue would be making the same change in a couple of other actions that have the same issue.

Happy to provide a patch if people think this is a reasonable solution. Thank-you for all your work on rules!

jonathan1055’s picture

to change the param to accept a string (langcode) instead of a language object, since this is all it uses anyway

Yes that is exactly what I was thinking, I have discussed it with TR and have already started work on it. One action and one condition already coded and working locally.

I was concerned about backwards compatibility, but now that you have confirmed the issue I don't think anyone can actually have a rule that uses the language option

You are right. The data selection gives the errors as in #6, and if using direct input text you get the error
Warning: preg_match_all() expects parameter 2 to be string, object given in Drupal\typed_data\PlaceholderResolver->scan() (line 197 of ___/typed_data/src/PlaceholderResolver.php).
This would have been solved in the Typed Data Widgets issue by changing the context to "entity:configurable_language" but a simpler solution is to accept a text value of langcode.

I will finish the work to do all the actions and conditions and post it here.

jonathan1055’s picture

Hi joel_osc
I have added a new patch #170 on #2471481-170: Integrate Typed Data Widgets which should allow you to pick your node.field_mgr_approver.entity.preferred_langcode.language field for the language in your rule. Would you be able to test that patch and let us know how it goes?
Thanks

joel_osc’s picture

Sure will do, thank-you so much!

joel_osc’s picture

Hi @jonathon1055, your changes work - I can now add node.field_mgr_approver.entity.preferred_langcode.language for the language and if I place a dpm($langcode) in doExecute it is the correct language ('fr' in my case). The actual email is not sent in the correct language, but I am thinking it would be best to open a new issue on that.

jonathan1055’s picture

Hey, pleased to hear that the language selection works.

Yes, raise a separate issue for the mail not respecting the language setting. Although I am not sure what exactly should happen. The subject and body are given (hard-coded) in your rule, so are you expecting those to be translated before sending? I don't think that could work, unless those strings are already in the "translation" store for the language required. But anyway, raise the new issue and we'll discuss it there.

joel_osc’s picture

Status: Active » Closed (duplicate)
Related issues: +#2471481: Integrate Typed Data Widgets

Sounds good, I will now close this issue as a duplicate of #2471481: Integrate Typed Data Widgets as that patch now fixes this problem. Cheers.

tr’s picture

Yeah, rules_mail() needs to be modified to properly translate subject and body. These strings are stored in the reaction rule configuration, so they are available for translating, but rules_mail() needs to actually use the translation. It can do that by wrapping the subject and body in t() and using the optional third argument to t() to specify the language code needed. It is allowed to use t() on a variable value here, because we know the string in that variable comes from configuration and so it exists in the translation table.

An example is in https://api.drupal.org/api/drupal/core%21modules%21contact%21contact.mod...