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
| Comment | File | Size | Author |
|---|---|---|---|
| #38 | 3059402-38.entity_integrity_check.patch | 7.65 KB | dotpex |
| #33 | 3059402-32.entity_integrity_check-test-only.patch | 2.32 KB | tr |
| #32 | interdiff_22-32.txt | 2.21 KB | budalokko |
| #32 | 3059402-32.entity_integrity_check.patch | 6.99 KB | budalokko |
| #22 | 3059402_entity_validation_23.yml.txt | 1.28 KB | jonathan1055 |
Issue fork rules-3059402
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
Comment #2
tr commentedYou 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)
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.
Comment #3
semanthis commentedPlease, 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...
I marked where I made my edit
Comment #4
semanthis commentedComment #5
tr commentedThe 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.
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.
Comment #6
semanthis commentedI hope I can make things clear by writing a step by step to reproduce:
1. add field
field_other_contenton Contenttypearticleas entity reference (refering to Contenttypepage).2. add field
field_field_to_modifyas Integer on Contenttypepage3. import this rule:
4. Add a condition "entity if of bundle"
Entity->Dataselector:
node.field_other_content.entityType->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:
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...
Comment #7
semanthis commentedComment #8
graysonecooper commented@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):
Note to self/others who are troubleshooting (probably mentioned elsewhere, but worth reiterating/double checking):
Comment #9
semanthis commentedThis issue is still open! What kind of information is needed, for You to understand the problem?
Comment #10
tr commentedI 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 ...
Comment #11
davide.porrovecchio commentedHi,
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.
Comment #12
davide.porrovecchio commentedComment #13
tree2009 commentedComment #14
tr commentedNeeds 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.
Comment #15
tree2009 commented3059402-11.patch is failed to test #3022250: Support inheritance in data type compatibility checking
rules-3022250-7.patch is failed to test #3059402: Set data action in referenced entity.
#2965726: Entity context fields fails on validation on update for entity reference is duplicated as 3059402.
#3121906: Node reference entity cannot acquired from "Entity is of type" or "Entity is of Bundle" is duplicated as 3059402.
#3088265: How to access a comment's parent-entity bundle-specific fields? is duplicated as 3059402.
Comment #16
tree2009 commentedcurrent 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 . ':') === 0all 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:
Comment #17
tr commentedYes, 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
Comment #18
tree2009 commentedre-roll the patch to compare with EntityAdapter::class and EntityReference::class
Comment #19
ConradFlashback commented#18 seems to solve the problem with entity reference field. But I still have to test it well.
Comment #20
ConradFlashback commentedI 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.
Comment #21
jimmynash commentedJust chiming in. #18 works for me on 3.0-alpha6. Thanks!
Comment #22
jonathan1055 commentedThanks @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)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.
Comment #23
wombatbuddy commentedPatch #22 fixes the issue.
Comment #24
wombatbuddy commentedComment #25
ConradFlashback commented@jonathan1055 #22 tested with last dev in my new project.
Great job thanks!
@TR please commit, this is a great improvement for Rules.
Comment #26
tr commentedLooks good but still needs tests, as mentioned in #14 and as tagged.
Comment #27
ConradFlashback commented@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.
Comment #28
tr commentedAs 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.
Comment #29
coolidfrez commentedGood 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 !
Comment #30
joseph.olstad@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'.
Comment #31
splash112 commentedCan confirm patch works, I can now select fields from a referenced entity in the user interface and fields get shown.
Comment #32
budalokko commentedAdded 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.
Comment #33
tr commentedThis 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.
Comment #35
aaronbaumanDoesn't look like this has changed substantially in 4.x
Comment #37
aaronbaumanOpened MR77, which is a straight reroll of #32 against 4.0.x
Also #32 was not applying to latest 3.x
Comment #38
dotpex commentedPatch reroll for 4.0.x