Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
The data type compatibility checking makes a simple equal comparison with special case of 'any' and 'entity' types. There is a @todo regarding of this at src/Context/ContextHandlerIntegrityTrait.php:
...
132 protected function checkDataTypeCompatible(CoreContextDefinitionInterface $context_definition, DataDefinitionInterface $provided, $context_name, IntegrityViolationList $violation_list
132 ) {
133 // Compare data types. For now, fail if they are not equal.
134 // @todo: Add support for matching based upon type-inheritance.
135 $target_type = $context_definition->getDataDefinition()->getDataType();
...
As far I can see, there is not an open issue for it.
Comments
Comment #2
manuel.adanThis is not a full solution, it improves the compatibility checking between entity type and sub-types (bundles). A reference to this issue also was added.
Comment #3
TR CreditAttribution: TR commentedNeed test cases for your changes added to Unit/Integration/Engine/IntegrityCheckTest.php
Can you give an example of where this patch helps? It's not clear to me that this will improve anything ...
Comment #4
TR CreditAttribution: TR commentedComment #5
manuel.adanI got this error submitting a an action form with one entity argument. The expected data type was "entity:transaction" (an entity type from the transaction module) and the provided was "entity:transaction:bundle_xxx", so they did not match despite they are compatible types.
The patch tries to solve similar scenarios, such as checking the target_type 'entity:node' with the provided 'entity:node:page'.
I just found that it could fail checking a type like 'entity:test' against 'entity:test2', so I reviewed it.
And currently, a checking like "entity" against "something_entity:something" would pass, however that would be a rare scenario. The patch also solves that.
Comment #6
TR CreditAttribution: TR commentedComment #7
akalam CreditAttribution: akalam at Metadrop commentedRe-rolled #5 against the latest -dev
Comment #8
drupalfan79 CreditAttribution: drupalfan79 commented@akalam could you export your rule and paste it here to test, thanks.
Comment #9
lukusProblem/Motivation
We've created a ruleset to set the schedule content moderation workflow state and schedule publishing time using actions.
In order to expose the necessary fields - we have added a condition to check for our bundle type. This functions correctly.
Later when we create the action to set the schedule publishing time, we hit a validation problem:
After debugging, I can see that a comparison is being made (in drupal/web/modules/contrib/rules/src/Context/ContextHandlerIntegrityTrait.php:140)
Proposed resolution
Attached a patch which solves the issue in a slightly different way to the others.
Comment #10
lukusUpdated patch to leave @todo comment, as after reading through related issues, I can see that these changes don't satisfy the larger requirements mentioned in this issue(i.e. matching integer for float context).
Comment #11
TR CreditAttribution: TR commentedWhat actions are you using? I would like to try to reproduce this. Are these Scheduler module actions? Previous posters didn't give complete information, notably leaving out information about the action used. I am curious about where entity:node:article comes from.
#2456831: [META] Add support for data type matching is more about type coercion - being able to cast a given type to the expected type. I think that can be handled independently from this issue, which is more about ensuring that subtypes can be used where the parent type is expected. Which IMO we shouldn't have to do explicitly, as this should be true at the language level, which is why I am wondering how to reproduced this. This error doesn't show up in anything I've used Rules for, which leads me to wonder whether some actions defined outside the Rules module have something to do with this.
We are going to need test cases using only Rules-defined actions that demonstrate this problem, so we can test to see if the proposed patches actually fix the problem without causing other problems.
Comment #12
lukusHi @TR
The main action we're using to set the Scheduler 'publish on' date is: scheduler_set_publishing_date_action
This action requires the node input is of entity type 'entity:node'
--
We need to restrict our action to only apply to a particular bundle type.
If we add a condition 'Node is of type', the resulting node object that's supplied to our schedule action is correct. I.e. the comparison is 'entity:node' to 'entity:node'.
However, we wish to access fields specific to our bundle type; so we've chosen use an 'Entity is of bundle' condition which allows us to traverse and access the fields specific to our chosen bundle.
... the drawback of this approach is the type of the resulting node object that's supplied to our schedule action includes the bundle. I.e. the comparison is 'entity:node:bundle' (from the supplied entity being action-ed) and 'entity:node' the type required by the Scheduler publish on action.
--
On a slightly tangential note, we originally tried to set the publish date using a generic 'Set a data value' action to a timestamp contained in a variable. This wasn't easily possible, so we resorted to using the specific action supplied by the Scheduler module.
Comment #13
TR CreditAttribution: TR commentedI really don't like what we're doing now, which is matching data types by string comparison of the name of the type. I don't really want to expand on that by trying to parse the string and make substring comparisons. That just seems wrong.
If you have a little time to work on this, my inclination would be to try to change
checkDataTypeCompatible()
to match based on class of the typed data object instead of the string data type name. So instead of:$target_type = $context_definition->getDataDefinition()->getDataType()
followed byif ($target_type != $provided->getDataType())
I would try to use something like
$target_class = $context_definition->getDataDefinition()->getClass()
followed by <if (!($provided->getClass() instanceof $target_class))
and of course there will probably still need to be special cases in the code, for example for our pseudo-type "any" and for entity references (which should be dereferenced so the pointed-to entity is the one used for comparison).
In fact, this is now sounding familiar ... after searching the issue queue I found #3059402-16: Set data action in referenced entity.. Maybe you can try the patch in #3059402-22: Set data action in referenced entity. and see if that solves this issue too?
Comment #14
lukusI agree!
It looks like this solves the exact issue! Thanks .. will try this out and report back.
Comment #15
lukusHey again @TR
Okay, so the patch in https://www.drupal.org/project/rules/issues/3059402#comment-13980031 does solve the issue I'm experiencing.
Looking at the resulting code, I can see that a string comparison is still occurring in various places.
If I was going to update the patch to compare based on class, would you agree it's more useful to provide the patch against this issue? The referenced issue seemed to start off as a more general query.
Comment #16
lukus