One of my most common tasks I used to use rules was to modify field data of a referenced entity after saving a entity. In the most primitive case I used this for just setting a backrefernce. In more complex cases do a math-operation with values from the referencing and the referenced entity and write the result into the referenced entity.
There where plenty of ways to get there. Either you could add a condition to the rule like node:field_reference:node is of bundle to get access to the fields of the referenced nodes or you could use the module rules conditional. A other approach was using components.

None of these options seem to exist in Rules for Drupal 8. I do not really understand, why this seems not to be important to anyone then me, because 90% of my rules in D7 where used to modify datas in other entities then the one that triggers the action.

As example: there is a Contenttype called "Basked" with a integer-field "Apples" and a Contenttype "eating apples" with a reference to the basked the eaten apples are taken from an an integer-field "quantity of eaten apples". Whenever You create a node of "eating apples" I would like to perform a action to subtract the "quantity of eaten apples" from "Apples" in the basket.

Creating such a rule in D6 or D7 was a task done in 5 minutes. And in D8 it seems to be ...

...impossible...

Is there any possibility to set field values other then body and title of a refernced entity. None of my attempts seem to work, not if I fetch the entity, not if use components, not by setting the conditions.

Any help would be highly appreciated

Issue fork rules-3059402

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

semanthis created an issue. See original summary.

tr’s picture

Category: Feature request » Support request
Status: Active » Fixed

You can find plenty of examples that do this if you search the issue queue. Here are two threads that have had posts within the past week - you don't have to look far: #3056966-6: entity is of bundle condition not working for eck entity types and #2872794-6: Adding new content (example)

None of my attempts seem to work

If the examples don't help, then you will need to export your rule and post it here along with a detailed list of steps you took, what you expected, what actually happened, and the errors you got, if any.

semanthis’s picture

Please, don't be annoyed, but the examples you presented have nothing to do with what I was talking about. I do not want to set a value into a new created content of a type but into a existing one. The problem starts with that I can't add a condition specifying what kind of content is referenced. If I try so, I'll end up with this:

rror: Call to undefined method Drupal\Core\TypedData\DataReferenceDefinition::setBundles() in Drupal\rules\Plugin\Condition\EntityIsOfBundle->assertMetadata() (line 67 of /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/modules/rules/src/Plugin/Condition/EntityIsOfBundle.php) #0 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/modules/rules/src/Context/ContextHandlerTrait.php(268): Drupal\rules\Plugin\Condition\EntityIsOfBundle->assertMetadata(Array) #1 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/modules/rules/src/Plugin/RulesExpression/ConditionExpression.php(205): Drupal\rules\Plugin\RulesExpression\ConditionExpression->assertMetadata(Object(Drupal\rules\Plugin\Condition\EntityIsOfBundle), Object(Drupal\rules\Engine\ExecutionMetadataState)) #2 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/modules/rules/src/Plugin/RulesExpression/ConditionExpression.php(186): Drupal\rules\Plugin\RulesExpression\ConditionExpression->prepareExecutionMetadataState(Object(Drupal\rules\Engine\ExecutionMetadataState), NULL, true) #3 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/modules/rules/src/Engine/ExpressionContainerBase.php(59): Drupal\rules\Plugin\RulesExpression\ConditionExpression->checkIntegrity(Object(Drupal\rules\Engine\ExecutionMetadataState), true) #4 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/modules/rules/src/Plugin/RulesExpression/RuleExpression.php(213): Drupal\rules\Engine\ExpressionContainerBase->checkIntegrity(Object(Drupal\rules\Engine\ExecutionMetadataState), true) #5 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/modules/rules/src/Engine/RulesComponent.php(275): Drupal\rules\Plugin\RulesExpression\RuleExpression->checkIntegrity(Object(Drupal\rules\Engine\ExecutionMetadataState)) #6 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/modules/rules/src/Form/EditExpressionForm.php(119): Drupal\rules\Engine\RulesComponent->checkIntegrity() #7 [internal function]: Drupal\rules\Form\EditExpressionForm->validateForm(Array, Object(Drupal\Core\Form\FormState)) #8 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/Form/FormValidator.php(82): call_user_func_array(Array, Array) #9 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/Form/FormValidator.php(275): Drupal\Core\Form\FormValidator->executeValidateHandlers(Array, Object(Drupal\Core\Form\FormState)) #10 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/Form/FormValidator.php(118): Drupal\Core\Form\FormValidator->doValidateForm(Array, Object(Drupal\Core\Form\FormState), 'rules_expressio...') #11 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/Form/FormBuilder.php(576): Drupal\Core\Form\FormValidator->validateForm('rules_expressio...', Array, Object(Drupal\Core\Form\FormState)) #12 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/Form/FormBuilder.php(319): Drupal\Core\Form\FormBuilder->processForm('rules_expressio...', Array, Object(Drupal\Core\Form\FormState)) #13 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/Controller/FormController.php(93): Drupal\Core\Form\FormBuilder->buildForm('rules_expressio...', Object(Drupal\Core\Form\FormState)) #14 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch)) #15 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array) #16 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/Render/Renderer.php(582): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #17 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #18 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) #19 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/vendor/symfony/http-kernel/HttpKernel.php(151): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #20 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/vendor/symfony/http-kernel/HttpKernel.php(68): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #21 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #22 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #23 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #24 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true) #25 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #26 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #27 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #28 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/DrupalKernel.php(693): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #29 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request)) #30 {main}.

OK that should be no problem because I can set a condition looking for the field in the referenced contentype. That would have made the field available in Drupal 7. But not here.
Asking for a export of my rule is somehow a strange question. I can't, because what I was writing is, that it is impossible to create such rule. I can do a export and manually edit it, how it should look like. I already did that because I thought it's trouble with the UI, but it does not work...

uuid: 4a725b82-c713-43e7-b12d-7168f2512f3f
langcode: de
status: true
dependencies: {  }
id: tankfuellstand_berechnen
label: 'Tankfüllstand berechnen'
events:
  -
    event_name: 'rules_entity_insert:node'
description: ''
tags: {  }
config_version: '3'
expression:
  id: rules_rule
  uuid: f6b47289-1d6a-4124-a80c-5f64fec62f88
  conditions:
    id: rules_and
    uuid: edec8c56-0605-4585-881c-2c501c0cef1d
    conditions:
      -
        id: rules_condition
        uuid: 35742b7d-02dd-4612-a8ba-de9ea7bd058e
        context_values:
          type: node
          bundle: tanken
        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: b8e88d7c-8a69-4e3b-917d-62d269b03754
        context_values: {  }
        context_mapping:
          entity: node
          field: node.field_entnahmetank
        context_processors: {  }
        provides_mapping: {  }
        condition_id: rules_entity_has_field
        negate: false
      -
        id: rules_condition
        uuid: c98798e5-74be-4617-9418-05f95b879312
        context_values:
          operation: '=='
          value: '5'
        context_mapping:
          data: node.field_art_des_tankens.target_id
        context_processors:
          operation:
            rules_tokens: {  }
          value:
            rules_tokens: {  }
        provides_mapping: {  }
        condition_id: rules_data_comparison
        negate: false
      -
        id: rules_condition
        uuid: 7237b9c5-9000-4d16-8b61-0584cb79f80a
        context_values:
          types:
            - tank
        context_mapping:
          node: node.field_entnahmetank.entity
        context_processors:
          types:
            rules_tokens: {  }
        provides_mapping: {  }
        condition_id: rules_node_is_of_type
        negate: false
      -
        id: rules_condition
        uuid: 2da69e2c-8280-4903-b717-6dfc17121313
        context_values:
          field: field_tankfuellung
        context_mapping:
          entity: node.field_entnahmetank.entity
        context_processors:
          field:
            rules_tokens: {  }
        provides_mapping: {  }
        condition_id: rules_entity_has_field
        negate: false
  actions:
    id: rules_action_set
    uuid: 2be882c3-2315-4642-a501-1311c15e2b3d
    actions:
      -
        id: rules_action
        uuid: e82a4e98-cd5c-416e-96fe-e5e8279947aa
        context_values:
          operator: '-'
        context_mapping:
<strong>          input_1: node.field_entnahmetank.entity.field_tankfuellung.value</strong>
          input_2: node.field_liter.value
        context_processors:
          operator:
            rules_tokens: {  }
        provides_mapping: {  }
        action_id: rules_data_calculate_value
      -
        id: rules_action
        uuid: 03803882-7eb0-43cf-9904-38d404644e74
        context_values: {  }
        context_mapping:
<strong>          data: node.field_entnahmetank.entity.field_tankfuellung.value</strong>
          value: result
        context_processors: {  }
        provides_mapping: {  }
        action_id: rules_data_set
      -
        id: rules_action
        uuid: 857574b7-c1a5-4acf-a9bc-40536deaa69e
        context_values:
          immediate: 'TRUE'
        context_mapping:
          entity: node.field_entnahmetank.entity
        context_processors:
          immediate:
            rules_tokens: {  }
        provides_mapping: {  }
        action_id: rules_entity_save
      -
        id: rules_action
        uuid: 5b369fed-3846-4964-a86a-de5b070afbc0
        context_values:
          type: notice
          repeat: false
        context_mapping:
          message: node.field_entnahmetank.entity.title.value
        context_processors:
          type:
            rules_tokens: {  }
          repeat:
            rules_tokens: {  }
        provides_mapping: {  }
        action_id: rules_system_message

I marked where I made my edit

semanthis’s picture

Status: Fixed » Active
tr’s picture

Status: Active » Postponed (maintainer needs more info)

The first sentence of your post said you were trying to "modify field data of a referenced entity after saving a entity". That's exactly what at least one of the examples does. And it works. So the likely problem here is that you're entering the wrong information in the UI, which is easy to do because the UI is unfinished.

You've claimed twice now that using "entity is of bundle" doesn't work. But it does - those examples I linked to show it working, and we have automated test cases to ensure it works and you can see in the project test results that it does. So saying the examples "have nothing to do with what I was talking about" is just wrong, or perhaps you didn't follow those links and try them out and see if you run those working examples on your site. And if you have additional problems beyond that, you should build on the working example and explain what you are trying to do, what you expect to happen, and what actually happens.

Amongst those examples are examples of using "node is of type" and "entity has field", along with "data set" and other actions. Importing those and looking at how they are configured is the best way to learn what is expected as input values in the UI.

Asking for a export of my rule is somehow a strange question. I can't, because what I was writing is, that it is impossible to create such rule.

It's not strange at all because you never said exactly what the problem is - you said "None of my attempts seem to work" but what does that mean? Does it mean you created a rule but it doesn't do what you think it should? Does it mean you created a rule but it generated an error when it ran? Does it mean you tried to save a rule and you got an error message? Does it mean you couldn't find the needed information in the data selector? Does it mean you couldn't get the event to fire, or that the condition didn't evaluate properly, or ... what ? How am I supposed to know you can't even save a rule, if you don't list the steps and tell us where you had problems and don't explain what those problems are?

An unedited export of the rule answers dozens of questions that you didn't volunteer information about, like exactly which events, conditions, and actions you are using, whether you entered values in the data selector or direct input, what tokens you used and whether you used the correct syntax for them, etc. And it would help if you would use a built-in content type and bundle like article as an example so that we could reproduce what you're trying to do without having to reproduce all of your site-specific configuration.

So the first step to solving your problem is to approach this systematically and add conditions/actions one-by-one. Use the "show a system message" action at each step to print out the tokens you're trying to use so you can see their values and figure out if you're using the correct one. Try the examples and see what values they use. This way you can determine specifically what is causing you problems and you will be able to ask a specific detailed question instead of just saying it doesn't work for you.

semanthis’s picture

I hope I can make things clear by writing a step by step to reproduce:

1. add field field_other_content on Contenttype articleas entity reference (refering to Contenttype page).

2. add field field_field_to_modify as Integer on Contenttype page

3. import this rule:

uuid: 673ee61e-eb71-4559-a57f-77d1c2c09968
langcode: en
status: true
dependencies: {  }
id: entity_refernce_error_demonstration_rule
label: 'Entity Refernce Error Demonstration Rule'
events:
  -
    event_name: 'rules_entity_insert:node'
description: 'this is a Rule to demonstrate a bug when adding a condition "Entity is of bundle" for a referenced entity.'
tags:
  - demo
config_version: '3'
expression:
  id: rules_rule
  uuid: 09b35859-3bfd-4e01-a091-a2305c761dc2
  conditions:
    id: rules_and
    uuid: e40b424d-8a33-45f3-af9f-933f5d1aac49
    conditions:
      -
        id: rules_condition
        uuid: 497b31d4-ebda-4141-b051-cc499ef93f0d
        context_values:
          type: node
          bundle: article
        context_mapping:
          entity: node
        context_processors:
          type:
            rules_tokens: {  }
          bundle:
            rules_tokens: {  }
        provides_mapping: {  }
        condition_id: rules_entity_is_of_bundle
        negate: false
  actions:
    id: rules_action_set
    uuid: a6fbc943-b56d-4969-9d54-5e529518f4df
    actions: {  }

4. Add a condition "entity if of bundle"
Entity->Dataselector: node.field_other_content.entity
Type->Value: node
Bundle->Value: page

5. Hit save - "The website encountered an unexpected error. Please try again later."
Error Message:
Error: Call to undefined method Drupal\Core\TypedData\DataReferenceDefinition::setBundles() in Drupal\rules\Plugin\Condition\EntityIsOfBundle->assertMetadata() (line 67 of /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/modules/rules/src/Plugin/Condition/EntityIsOfBundle.php) #0 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/modules/rules/src/Context/ContextHandlerTrait.php(268): Drupal\rules\Plugin\Condition\EntityIsOfBundle->assertMetadata(Array) #1 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/modules/rules/src/Plugin/RulesExpression/ConditionExpression.php(205): Drupal\rules\Plugin\RulesExpression\ConditionExpression->assertMetadata(Object(Drupal\rules\Plugin\Condition\EntityIsOfBundle), Object(Drupal\rules\Engine\ExecutionMetadataState)) #2 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/modules/rules/src/Plugin/RulesExpression/ConditionExpression.php(186): Drupal\rules\Plugin\RulesExpression\ConditionExpression->prepareExecutionMetadataState(Object(Drupal\rules\Engine\ExecutionMetadataState), NULL, true) #3 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/modules/rules/src/Engine/ExpressionContainerBase.php(59): Drupal\rules\Plugin\RulesExpression\ConditionExpression->checkIntegrity(Object(Drupal\rules\Engine\ExecutionMetadataState), true) #4 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/modules/rules/src/Plugin/RulesExpression/RuleExpression.php(213): Drupal\rules\Engine\ExpressionContainerBase->checkIntegrity(Object(Drupal\rules\Engine\ExecutionMetadataState), true) #5 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/modules/rules/src/Engine/RulesComponent.php(275): Drupal\rules\Plugin\RulesExpression\RuleExpression->checkIntegrity(Object(Drupal\rules\Engine\ExecutionMetadataState)) #6 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/modules/rules/src/Form/EditExpressionForm.php(119): Drupal\rules\Engine\RulesComponent->checkIntegrity() #7 [internal function]: Drupal\rules\Form\EditExpressionForm->validateForm(Array, Object(Drupal\Core\Form\FormState)) #8 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/Form/FormValidator.php(82): call_user_func_array(Array, Array) #9 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/Form/FormValidator.php(275): Drupal\Core\Form\FormValidator->executeValidateHandlers(Array, Object(Drupal\Core\Form\FormState)) #10 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/Form/FormValidator.php(118): Drupal\Core\Form\FormValidator->doValidateForm(Array, Object(Drupal\Core\Form\FormState), 'rules_expressio...') #11 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/Form/FormBuilder.php(576): Drupal\Core\Form\FormValidator->validateForm('rules_expressio...', Array, Object(Drupal\Core\Form\FormState)) #12 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/Form/FormBuilder.php(319): Drupal\Core\Form\FormBuilder->processForm('rules_expressio...', Array, Object(Drupal\Core\Form\FormState)) #13 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/Controller/FormController.php(93): Drupal\Core\Form\FormBuilder->buildForm('rules_expressio...', Object(Drupal\Core\Form\FormState)) #14 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch)) #15 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array) #16 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/Render/Renderer.php(582): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #17 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #18 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) #19 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/vendor/symfony/http-kernel/HttpKernel.php(151): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #20 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/vendor/symfony/http-kernel/HttpKernel.php(68): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #21 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #22 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #23 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #24 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true) #25 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #26 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #27 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #28 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/core/lib/Drupal/Core/DrupalKernel.php(693): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #29 /is/htdocs/wp1083767_SESE1KG4Q0/tankbuch/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request)) #30 {main}.

6. Import Reaction Rule:

uuid: 673ee61e-eb71-4559-a57f-77d1c2c09968
langcode: en
status: true
dependencies: {  }
id: entity_refernce_error_demonstration_rule
label: 'Entity Refernce Error Demonstration Rule'
events:
  -
    event_name: 'rules_entity_insert:node'
description: 'this is a Rule to demonstrate a bug when adding a condition "Entity is of bundle" for a referenced entity.'
tags:
  - demo
config_version: '3'
expression:
  id: rules_rule
  uuid: 09b35859-3bfd-4e01-a091-a2305c761dc2
  conditions:
    id: rules_and
    uuid: e40b424d-8a33-45f3-af9f-933f5d1aac49
    conditions:
      -
        id: rules_condition
        uuid: 497b31d4-ebda-4141-b051-cc499ef93f0d
        context_values:
          type: node
          bundle: article
        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: 7865d1a7-2d42-4fd1-bb30-0b9d2f285d02
        context_values:
          types:
            - page
        context_mapping:
          node: node
        context_processors:
          types:
            rules_tokens: {  }
        provides_mapping: {  }
        condition_id: rules_node_is_of_type
        negate: false
      -
        id: rules_condition
        uuid: fd5c22ec-1310-460e-8beb-018b6df7c9ba
        context_values:
          field: field_field_to_modify
        context_mapping:
          entity: node.field_other_content.entity
        context_processors:
          field:
            rules_tokens: {  }
        provides_mapping: {  }
        condition_id: rules_entity_has_field
        negate: false
  actions:
    id: rules_action_set
    uuid: a6fbc943-b56d-4969-9d54-5e529518f4df
    actions: {  }

7. Add action "set data value" -> switch to data selection

8. Try to select node.field_other_content.entity.field_field_to_modify -> This field is not selectable!

9. Manually enter node.field_other_content.entity.field_field_to_modify into the input and set value to 1

10. Hit save -> rule will save and works as it should!!! (but it can't be modified with UI after flushing cache - it can only beeing edited by exporting, manually editing and reimporting)

11. Flush cache

12. Edit Action: Set a data value

13. Hit save without any modification -> error message "Data selector node.field_other_content.entity.field for context Data is invalid. Unable to apply data selector 'field_other_content.entity.field' at 'field_other_content.entity.field' "

I solved my issues with the workaround by writing my rules as yml-files and importing them. It's still faster then writing a module, but that is no real solution.
Please don't missunderstand me. I'm very thankful that You take care for rules. I'm no developer my job is to sit together with customers to do not rapid prototyping but to do instant prototyping. I have to realize functions while the customer is talking. Drupal 7 with rules, Views, Entity Reference, Views Rules and Conditional Rules and Search API, still is the most unbelivable setup to do my job. What I do is all about speed, so rules is essential to me, and I start to get nervous because my developers start complaining that I still use D7.
As I said I'm not really qulified to contribute code. But as soon as rules is on beta-stage I would be definetly willed to sponsor porting the Views Rule module to D8. Will You be at DrupalCon Amsterdam this autumn? Please let me know, because I think I owe You a drink for beeing so annoying...

semanthis’s picture

Category: Support request » Bug report
graysonecooper’s picture

@TR, first off, thanks for all of your work on this module! (and the Typed Data and the Rules Essentials modules!) It's been really amazing to watch the issue queue evaporate. As Rules is the main reason I haven't made the switch to D8 yet, I'm encouraged I'll be able to soon.

I seem to be running into the same issue as @semanthis here. I've done the following (note, I'm running latest -dev versions of rules, typed data, with Rules Essentials):

  1. Added Condition for Entity is of Bundle for originating node (successful, and loads all custom fields in autocomplete, nice!)

  2. Added Condition for Entity has Field for entity reference field (seems duplicative, but would rather be safe)

  3. Added Condition for Entity is of Bundle for target node from entity reference field (Use data selector: node.field_entity_reference.entity, Get a WSOD error: Call to undefined method Drupal\Core\TypedData\DataReferenceDefinition::setBundles() in Drupal\rules\Plugin\Condition\EntityIsOfBundle->assertMetadata() (line 67), same for using data selector node.field_entity_reference)

  4. Instead, use Conditions for Entity is of Type & Node is of Type to set these conditions separately for target node, again use Entity has Field for good measure

  5. When I try to post a message on the site using the data selector: "node.field_entity_reference.entity.field_indicator, I get "Data selector node.entity_reference.entity.field_indicator for context Message is invalid. Unable to apply data selector 'field_entity_reference.entity.field_indicator' at 'field_entity_reference.entity.field_indicator' (Note: I'm just using the display a message as debugging. I want to do the same as @semanthis and actually update the value in this field; otherwise I would use tokens as described below)

Note to self/others who are troubleshooting (probably mentioned elsewhere, but worth reiterating/double checking):

  1. Pay attention to whether you are using data selection or direct input!
  2. If you just need to get a value, use direct input AND use tokens - this works SO well!
  3. If you need to access a field, tokens don't help, must use data selection
  4. Clear caches!
semanthis’s picture

This issue is still open! What kind of information is needed, for You to understand the problem?

tr’s picture

I just haven't had time to try to confirm the issue using the information you provided in #6. And I certainly haven't had time to work on a solution with all the other things I'm trying to get done with Rules. This issue doesn't affect me personally right now and I have a lot of other work to do ...

davide.porrovecchio’s picture

Status: Postponed (maintainer needs more info) » Needs review
StatusFileSize
new1.92 KB

Hi,
I can reproduce the bug described by semanthis.
I digged into the code and found that referenced entities were not supported in the "Entity is of bundle" condition.
Here is attached a simple patch that is working for me.

davide.porrovecchio’s picture

StatusFileSize
new1.92 KB
tree2009’s picture

Status: Needs review » Reviewed & tested by the community
tr’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

Needs tests to demonstrate the problem and prove the fix.

Also, need to consolidate the other two or three open issues that talk about problems with entity references and make sure this fix addresses all those use cases. For example #3022250: Support inheritance in data type compatibility checking, #2965726: Entity context fields fails on validation on update for entity reference, #3121906: Node reference entity cannot acquired from "Entity is of type" or "Entity is of Bundle", #3088265: How to access a comment's parent-entity bundle-specific fields? and perhaps others.

tree2009’s picture

current module supports to compare:
entity vs. entity:node
its code:
$target_type == 'entity' && strpos($provided->getDataType(), 'entity:') !== FALSE

#3059402: Set data action in referenced entity. try to compare:
entity vs. entity_reference
its patch:
$target_type == 'entity' && preg_match('/entity[:_]/', $provided->getDataType()) != FALSE

#3022250: Support inheritance in data type compatibility checking try to compare:
entity:node vs. entity:node:page
its patch:
strpos($target_type, 'entity') === 0 && strpos($provided->getDataType(), $target_type . ':') === 0

all of above three solutions try to compare type with string or preg function, alternatively, we can compare the classes in common way, they are equal if their classes are EntityAdapter or EntityReference:

$context_definition->getDataDefinition()->getClass() == 'Drupal\Core\Entity\Plugin\DataType\EntityAdapter' && ($provided->getClass() == 'Drupal\Core\Entity\Plugin\DataType\EntityAdapter' || $provided->getClass() == 'Drupal\Core\Entity\Plugin\DataType\EntityReference')
tr’s picture

Yes, I would much rather do type checking instead of string comparison.

We should use EntityAdapter::class instead of 'Drupal\Core\Entity\Plugin\DataType\EntityAdapter', and likewise for EntityReference

tree2009’s picture

StatusFileSize
new2.41 KB

re-roll the patch to compare with EntityAdapter::class and EntityReference::class

ConradFlashback’s picture

#18 seems to solve the problem with entity reference field. But I still have to test it well.

ConradFlashback’s picture

I confirm, #18 saves me in two different projects.
I can now create bundle conditions for referenced field and complex rules with different entities.

Please @TR verify if this patch has not problem with other codes, and commit this.

jimmynash’s picture

Just chiming in. #18 works for me on 3.0-alpha6. Thanks!

jonathan1055’s picture

Status: Needs work » Needs review
StatusFileSize
new4.67 KB
new1.28 KB

Thanks @davide.porrovecchio for the initial patch and @drupalfan79 for the updated patch using EntityAdapter::class and EntityReference::class. Thanks also to @ConradFlashback and @jimmynash for testing. This is good progress.

I have reproduced the errors reported by @semanthis in #6 however since June 2019 there have been improvements to the Rules validation, because if the referenced field_field_to_modify is not shown in the auto-complete then you cannot just type the value and save (as per #6.9 and #6.10). However, you can export the rule, edit the field name, re-import and it works as expected.

I also reproduced the steps from @graysonecooper in #8. Adding the second 'Entity is of bundle' gives the error "Call to undefined method Drupal\Core\TypedData\DataReferenceDefinition::setBundles()" which is fixed by the change to EntityIsOfBundle.php. Then we get the error "Expected a entity data type for context Entity but got a entity_reference data type instead" which is fixed by the change to ContextHandlerIntegrityTrait.php

The problem of not being able to select the field on the referenced entity is not addressed by the patch as is stands, so that is still work to do.

Regarding the changes to ContextHandlerIntegrityTrait::checkContextConfigIntegrity() the new validation allows any entity_reference to be considered valid, and this can lead to later failures at runtime. To demonstrate this, create the following rule (which is also attached for import)

  • Event: Before saving content
  • Condition: Entity is of bundle: node, node, article
  • Action: Promote content to front page: node

Without any patch we get the usual "Expected a entity:node data type for context Node but got a entity:node:article data type instead."
With patch #18 the value in the action is accepted, which is good. But it also allows a node value of 'node.uid.entity'. This passes validation but obviously fails badly at runtime.

This can be improved by getting the 'constraint' entity type from the entity_reference and checking that it matches with the target_type. For the example above, $provided->getConstraints()['entityType'] is 'user' which should not be allowed when the target_type is 'entity:node'. When selecting just 'node' the constraint entityType is 'node' so this can be accepted as a valid entity_reference. Patch #22 includes this change. In doing so, we can also improve the violation message to say what type of entity_reference was provided, if it failed to match. So entering 'node.uid.entity' now gives "Expected a entity:node data type for context Node but got a user entity_reference data type instead". The difference is the addition of the incorrect referenced entity type 'user'.

The patch looks more complex, but this is because I have separated out each check which validates and has a return, so that we can see more clearly what is being done. Then the final violation code is no longer indented as it is not in a conditional block. I also removed a duplicated variable $expected_type_problem which was identical to $target_type.

I will write some tests to demonstrate the probelm and show that it is fixed here, as @TR requested. Also we need to re-check that list of other issues as @drupalfan79 did. However, I wanted to share the updated patch here now, to get some feedback.

wombatbuddy’s picture

Patch #22 fixes the issue.

wombatbuddy’s picture

Status: Needs review » Reviewed & tested by the community
ConradFlashback’s picture

@jonathan1055 #22 tested with last dev in my new project.
Great job thanks!
@TR please commit, this is a great improvement for Rules.

tr’s picture

Status: Reviewed & tested by the community » Needs work

Looks good but still needs tests, as mentioned in #14 and as tagged.

ConradFlashback’s picture

@TR

#3022250: Support inheritance in data type compatibility checking
Author confirms patch 22 solved your problem. This patch uses EntityAdapter and has validate system.

#2965726: Entity context fields fails on validation on update for entity reference
#3121906: Node reference entity cannot acquired from "Entity is of type" or "Entity is of Bundle"
#3088265: How to access a comment's parent-entity bundle-specific fields?
They are simple duplications of this issue.

Please TR commits this in a next dev version. I'm not a developer but everything works well in my three projects with complex rules entity referenced.

tr’s picture

As I said in #26, this still needs test cases for the automated testing. I won't commit this without tests cases - that's a basic requirement and that's half the work of fixing problems like this.

coolidfrez’s picture

Good day everyone,

Use with comment and it works well.

Use case :
Event :
After saving a new comment

Conditions :
Entity is of bundle
Parameters: entity: comment.entity_id.entity, type: node, bundle: message

Data to compare
Parameters: data: comment.entity_id.entity.field_suivre_par_mail.value, operation: ==, value: 1

Action :
Send mail

So I check if the new comment is "attached" to a node entity (bundle : message) with the option to follow by mail (a simple checkbox).

Many many tks !

joseph.olstad’s picture

@coolidfrez, while your use case works, my use case requires a data comparison for a custom field from a user entity in the 'Conditions'.

I've followed about 15 threads on this subject however while I am able to get this user entity custom field to be working in the 'Actions', it is not available/not working in the 'Conditions'.

splash112’s picture

Can confirm patch works, I can now select fields from a referenced entity in the user interface and fields get shown.

budalokko’s picture

Status: Needs work » Needs review
StatusFileSize
new6.99 KB
new2.21 KB

Added a Kernel test to patch in #22 as there's some agreement on it being a working solution.

Please @TR let me know if there is any additional test you think would be reasonable to add and I could try to add too.

tr’s picture

This is just the tests from patch #32. What I'm looking for is tests that FAIL with the current version of Rules, but PASS with the patched version of Rules. That will demonstrate that there is a problem with the current version and will also demonstrate that the patch fixes the problem. Also, that gives us confidence that if this feature gets broken in the future that the test will catch it.

Status: Needs review » Needs work

The last submitted patch, 33: 3059402-32.entity_integrity_check-test-only.patch, failed testing. View results

aaronbauman’s picture

Version: 8.x-3.x-dev » 4.0.x-dev

Doesn't look like this has changed substantially in 4.x

aaronbauman’s picture

Status: Needs work » Needs review

Opened MR77, which is a straight reroll of #32 against 4.0.x

Also #32 was not applying to latest 3.x

dotpex’s picture

StatusFileSize
new7.65 KB

Patch reroll for 4.0.x