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 Rules event redispatcher does not pass on the event context supplied by GenericEvent and its sub classes.
This is caused by several problems, resolved in a patch I will supply.
- For instanceof to work correctly, a use statement must define the exact class you want to match (GenericEventSubscriber,php)
- To correctly save a ReactionRule as a ConfigEntity instance, createInstance() needs to be called with the correct entity_type_id of rules_reaction_rule. I've added a convenience method to ExpressionManagerInterface.php and ExpressionManager.php
- The event information is not passed to the rules_config as currently written. The ReactionRule entity code now adds it to the configuration before the ReactionRule expression class instantiates itself
- A couple of tests will need to be added to test this; I will probably need some advice how best to do this.
Comment | File | Size | Author |
---|---|---|---|
#3 | stuff.diff | 1.6 KB | Torenware |
Comments
Comment #2
Torenware CreditAttribution: Torenware as a volunteer commentedLooks like Klausi just created a createReactionRule method, so I'll remove that from my patch.
Comment #3
Torenware CreditAttribution: Torenware as a volunteer commentedI'm adding a quick diff file to show the change, sans test, which I'm working on now.
When I have the test set up, I'll create a PR.
Comment #4
Torenware CreditAttribution: Torenware as a volunteer commentedThe problem is actually worse than I thought. In my opinion, the RulesState is needlessly isolated from Action and Configuration plugins.
Here's the problem.
Look at ContextHandlerTrait::mapContext(). Here's the problem code:
The problem here is that unless a plugin asks for a piece of data by name via its annotation, Event data will never be seen by the plugin. Even if manipulating $this->configuration['context_mapping'] wasn't a PITA (and yeah, there's no good API access right now)., there is absolutely no flexibility for data access in the plugins.
I wrote a number of Rules 7.x-2.x actions and conditions that were only possible because the RulesState information was available to the call back. IT REALLY NEEDS TO BE THERE IN 8.x-3.x AS WELL.
In particular, the following test code CANNOT WORK in the current implementation:
What I'm trying to do here is very simple, and is something that people often need to do: manipulate the data passed in via the event, or test items in it. 'context_name' and 'log_missing' are defined in the action plugin's annotation. And the ReactionRules event, rules_user_login, passes a user object as "account". But the event data will NEVER get to this point.
I'm not sure what mapContext() is intended to do, but if at all possible, I'd love to see it just go away.
Is there any reason why the RuleState cannot be directly available to the executing plugins, without the additional complexity of this mapping process?
This is, in my opinion, a serious problem in the Rules processing pipeline.
Comment #5
Torenware CreditAttribution: Torenware as a volunteer commentedRaising the priority to get your collective attention. RulesState needs to get passed where plugin in code can actually get at it. Current implementation makes that impossible.
Comment #7
klausiOh yes, the missing use statement was a good find, committed a fix for this. What else is missing here?
mapConext() must stay in Rules because we need to map variables names from the Rules state to variable names in the action plugin. Example: if an event provides a variable "text" and a logging action uses a context "message" then we need to map the variable "text" to "message".
Comment #8
Torenware CreditAttribution: Torenware as a volunteer commentedIs there any way to make the RulesState object accessible to plugins during the process?
Certainly, we need to map variable names. But right now, the process also excludes data. It seems to me that if the event supplies data, it should be visible to conditions and to actions, at least so we can introspect the objects. But with the way we map context right now, if something is not explicitly named, it's not in the context at all. This is different from Drupal 7, where the callbacks got the RuleState as an argument.
Comment #9
klausiCurrently the RulesState is not part of any RulesAction plugin or Condition interface. An action or condition should not know anything about state. They receive all their necessary data through context definitions. Additional API functions such as autoSaveContext() and refineContext() are used to cover that cases.
Conditions don't need to look at all variables that are currently in the RulesState. Whatever they need should be mapped into them as context.
Could you describe the use case of your action/condition so that we can understand the need for the RulesState better?
Comment #10
Torenware CreditAttribution: Torenware as a volunteer commentedHere's 3 use cases where it's useful to have direct access to RulesState.
Part of what I'm looking at in the 3.x source base is how these kinds of things can be done. Right now, it looks like it's going to be at least as hard in 3.x as currently written as it was in 2.x.
I'd like to turn the question around, as well. You say
Why is this? Is there some particular reason that actions and conditions need to be isolated from the rules that call them? In a lot of Drupal code, we go around this kind of isolation. Why should Rules be different in this regard?
Also:
Some additional documentation would help a lot here. I don't see a refineContext() -- there is, however, a refineContextDefintions(), which is called w/o arguments -- although I've seen autoSaveContext(). But cannot tell from the very short doc comments what they are supposed to do:
Selectors can be used for some things as well, I know, but they are pretty complex and not all that well documented either.
If we can do something that is as simple as possible to understand, document and debug, I think we're helping ourselves and we're helping the community.
Comment #11
fagoWhat about making the rules state another context that a plugin may decide to receive? That way it automatically makes the action/condition rules specific, it makes the usage explicit and it sitll works in the case it needs to.
Comment #12
Torenware CreditAttribution: Torenware as a volunteer commentedfago,
Yeah, that would likely work. It's not as transparent as simply writing over the state, but yeah, it would be possible at least to see it.
Comment #13
TR CreditAttribution: TR commented@Torenware, are you still planning to work on this?
Comment #14
TR CreditAttribution: TR commentedI guess not.