Ensure all user events use the user object instead of account

Created on 14 June 2022, over 2 years ago
Updated 9 July 2024, 6 months ago

Problem/Motivation

I've created a rule that sends an email both when a new user of a certain role type registers, and also when a user of the same role type logs in. I rolled both events into the same rule, as the email goes to the same email account.

The rule works without error when the user registers, but when the user uses their one-time-login to login the rule fails with a white screen with this error:

The website encountered an unexpected error. Please try again later.

Drupal\rules\Exception\EvaluationException: Unable to get variable 'user'; it is not defined. in Drupal\rules\Context\ExecutionState->getVariable() (line 106 of modules/contrib/rules/src/Context/ExecutionState.php).

Drupal\rules\Context\ExecutionState->fetchDataByPropertyPath('user') (Line: 62)
Drupal\rules\Plugin\RulesExpression\ConditionExpression->prepareContext(Object, Object) (Line: 119)
Drupal\rules\Plugin\RulesExpression\ConditionExpression->executeWithState(Object) (Line: 38)
Drupal\rules\Plugin\RulesExpression\AndExpression->evaluate(Object) (Line: 79)
Drupal\rules\Engine\ConditionExpressionContainer->executeWithState(Object) (Line: 112)
Drupal\rules\Plugin\RulesExpression\RuleExpression->executeWithState(Object) (Line: 33)
Drupal\rules\Plugin\RulesExpression\ActionSetExpression->executeWithState(Object) (Line: 161)
Drupal\rules\EventSubscriber\GenericEventSubscriber->onRulesEvent(Object, 'rules_user_login', Object)
call_user_func(Array, Object, 'rules_user_login', Object) (Line: 142)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'rules_user_login') (Line: 102)
rules_user_login(Object)
call_user_func_array('rules_user_login', Array) (Line: 403)
Drupal\Core\Extension\ModuleHandler->invokeAll('user_login', Array) (Line: 473)
user_login_finalize(Object) (Line: 245)
Drupal\user\Controller\UserController->resetPassLogin('6424', '1655243386', 'VnZMIgLHaLc-OCU9PFCSzTLFoD8aPJtOUcIm92MJZKM', Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 564)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 158)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 80)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 708)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

Puzzled as to why the rule works for one event but not the other.

Steps to reproduce

This is an export of my rule:
langcode: en
status: true
dependencies: { }
id: ams_login_notify
label: 'login Notify'
events:
-
event_name: 'rules_entity_insert:user'
-
event_name: rules_user_login
description: ''
tags: { }
config_version: '3'
expression:
id: rules_rule
uuid: 9b816212-93b2-419b-aa4f-3444b0815a06
weight: 0
conditions:
id: rules_and
uuid: 52da032c-fe1d-4df7-9061-ac8cebe3a85d
weight: 0
conditions:
-
id: rules_condition
uuid: 843a4aad-43b7-4ce4-bd5b-7e8a5dcc6dfc
weight: 0
condition_id: rules_user_has_role
negate: false
context_values:
roles:
- customers_ams_
operation: AND
context_mapping:
user: user
context_processors:
roles:
rules_tokens: { }
operation:
rules_tokens: { }
provides_mapping: { }
actions:
id: rules_action_set
uuid: e8b2c5f0-5e16-4299-ad5c-494412cd13c5
weight: 0
actions:
-
id: rules_action
uuid: e7c4775b-0d70-4933-963e-c044833b4a55
weight: -49
action_id: rules_send_email
context_values:
to:
- test@test.com
subject: 'Customer (AMS ) Registration Notification'
message: "Hello,\r\n\r\nThe following user has registered using the custom customer-ams registration form.\r\n\r\nModerate this profile here:link"
reply: ''
language: ''
context_mapping: { }
context_processors:
to:
rules_tokens: { }
subject:
rules_tokens: { }
message:
rules_tokens: { }
reply:
rules_tokens: { }
language:
rules_tokens: { }
provides_mapping: { }

✨ Feature request
Status

Needs review

Version

4.0

Component

Rules Core

Created by

πŸ‡¨πŸ‡¦Canada OMD

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Updated my website with the following changes:
    Drupal Version
    9.4.x => 9.5.10

    PHP Version
    8.0 => 8.1.14

    Version of Drupal Rules:

    "drupal/rules": "^3.0@alpha",

    After patching the iterator error: https://www.drupal.org/project/rules/issues/3243962 πŸ“Œ Prepare for PHP 8.1 Fixed

    I received the next following error:

    Deprecated function: preg_match_all(): Passing null to parameter #2 ($subject) of type string is deprecated in Drupal\typed_data\PlaceholderResolver->scan() (line 185 of modules/contrib/typed_data/src/PlaceholderResolver.php).
    Drupal\typed_data\PlaceholderResolver->scan(NULL) (Line: 63)
    Drupal\rules\Plugin\RulesDataProcessor\TokenProcessor->process(NULL, Object) (Line: 320)
    Drupal\rules\Plugin\RulesExpression\ConditionExpression->processValue(NULL, Array, Object) (Line: 297)
    Drupal\rules\Plugin\RulesExpression\ConditionExpression->processData(Object, Object) (Line: 83)
    Drupal\rules\Plugin\RulesExpression\ConditionExpression->prepareContext(Object, Object) (Line: 119)
    Drupal\rules\Plugin\RulesExpression\ConditionExpression->executeWithState(Object) (Line: 38)
    Drupal\rules\Plugin\RulesExpression\AndExpression->evaluate(Object) (Line: 79)
    Drupal\rules\Engine\ConditionExpressionContainer->executeWithState(Object) (Line: 112)
    Drupal\rules\Plugin\RulesExpression\RuleExpression->executeWithState(Object) (Line: 33)
    Drupal\rules\Plugin\RulesExpression\ActionSetExpression->executeWithState(Object) (Line: 147)
    Drupal\rules\EventSubscriber\GenericEventSubscriber->onRulesEvent(Object, 'rules_user_login', Object)
    call_user_func(Array, Object, 'rules_user_login', Object) (Line: 142)
    Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, Object) (Line: 102)
    rules_user_login(Object)
    call_user_func_array(Object, Array) (Line: 426)
    Drupal\Core\Extension\ModuleHandler->Drupal\Core\Extension\{closure}(Object, 'rules') (Line: 405)
    Drupal\Core\Extension\ModuleHandler->invokeAllWith('user_login', Object) (Line: 433)
    Drupal\Core\Extension\ModuleHandler->invokeAll('user_login', Array) (Line: 476)
    user_login_finalize(Object) (Line: 171)
    Drupal\user\Form\UserLoginForm->submitForm(Array, Object)
    call_user_func_array(Array, Array) (Line: 114)
    Drupal\Core\Form\FormSubmitter->executeSubmitHandlers(Array, Object) (Line: 52)
    Drupal\Core\Form\FormSubmitter->doSubmitForm(Array, Object) (Line: 597)
    Drupal\Core\Form\FormBuilder->processForm('user_login_form', Array, Object) (Line: 325)
    Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 73)
    Drupal\Core\Controller\FormController->getContentResult(Object, Object)
    call_user_func_array(Array, Array) (Line: 123)
    Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 580)
    Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
    Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
    Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 169)
    Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
    Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
    Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
    Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
    Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
    Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
    Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
    Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
    Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 718)
    Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
    

    There is discussion to protect the Drupal core from this error here: https://www.drupal.org/project/drupal/issues/3294680 πŸ› PHP8.1 deprecation: str_replace(): Passing null to parameter #3 Needs work

    But the concensus here seems to be that individual modules are likely the cause of these errors, but even so the core should have some protections against these module errors.

    When attempting to add the patch I discovered that changing my version to

    "drupal/rules": "3.x-dev",

    allows the patch, but then it breaks the patch for the iterator error: https://www.drupal.org/project/rules/issues/3243962 πŸ“Œ Prepare for PHP 8.1 Fixed and vice versa.

  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 9.5.5 + Environment: PHP 7.3 & MySQL 5.7
    last update over 1 year ago
    Patch Failed to Apply
  • Created a patch for 8.x-3.0-alpha7 with the changes suggested by TR in Comment #10. https://www.drupal.org/project/rules/issues/3285721#comment-14574248 ✨ Unable to get variable 'user' Needs review

  • I resolved my issue:

    Diving into the code for the errors I added logs for the following code as mentioned in the error (Drupal\rules\Plugin\RulesExpression\ConditionExpression->processData(Object, Object) (Line: 83));

    Relative path to file: web/modules/contrib/rules/src/Context/ContextHandlerTrait.php

    I found that I were I was hitting two rules I had set up. I decided to delete the 2 previous rules I had made, and remake them. This actually solved this error. I am not sure if the patches (found here: https://www.drupal.org/project/rules/issues/3285721#comment-15186484 ✨ Unable to get variable 'user' Needs review && https://www.drupal.org/project/drupal/issues/3294680 πŸ› PHP8.1 deprecation: str_replace(): Passing null to parameter #3 Needs work ) are also contributing in some way to the making new rules and deleting the old ones.

  • πŸ‡ΊπŸ‡ΈUnited States tr Cascadia

    There are two distinct errors being talked about here.

    The one in the issue summary, "Unable to get variable 'user'" is the one that is fixed by the patch. I understand 100% why that error occurs and I am 100% positive the patch in #7 fixes the problem. The only reason it hasn't been committed yet is because we need an update hook to properly update any existing Rules that may be configured on a particular site. But for new installations without any Rules configured, it will always work.

    I found that I were I was hitting two rules I had set up. I decided to delete the 2 previous rules I had made, and remake them. This actually solved this error.

    @mtaggart@s-5.com: Yes, this is exactly why an update hook is needed - the patch will fix it so any new Rules created after the patch work, but it won't fix old Rules using those event that were created before the patch.

    The second error, "Passing null to parameter #2 ($subject)", is different.
    That error is discussed in a number of different open issues, notably πŸ› preg_match_all(): Passing null to parameter #2 ($subject) of type string is deprecated Fixed . It's really out of scope to pursue a solution here in this issue. I do not want this issue to become an open-ended support issue for whatever problems a given person has encountered. It should remain focused on only that first error, and only on the patch in #7.

    If you would like to see this resolved and committed to Rules, you can help by writing the update hook.

  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 10.1.x + Environment: PHP 8.2 & MySQL 8
    last update about 1 year ago
    414 pass
  • πŸ‡ΊπŸ‡ΈUnited States tr Cascadia
  • πŸ‡ΊπŸ‡ΈUnited States tr Cascadia
  • πŸ‡ΊπŸ‡ΈUnited States tr Cascadia

    I turned the patch into an MR for Rules 4.0.x.
    The status is still as described in #22 - this still needs an update hook.
    Also, should probably figure out how to add deprecation notices for this in 8.x-3.x, for BC purposes, to help any contributed modules that might be using these events.

  • πŸ‡ΊπŸ‡ΈUnited States tr Cascadia
Production build 0.71.5 2024