Call to a member function id() on string in UserHasRole.php

Created on 9 March 2023, over 1 year ago
Updated 9 August 2024, 4 months ago

Similar to issue # 3088481 (https://www.drupal.org/project/rules/issues/3088481) β†’ , I've found that the same issue exists in UserHasRole.php and can be fixed with the same fix as that described in issue # 3088481.

I found issue # 2824360 (Error "Call to a member function id() on string" for condition 'user has role(s)') β†’ which should have fixed the issue, but unfortunately it had no effect and has been marked closed, so I'm opening a new issue in the hopes of providing it with more visibility.

Problem/Motivation

A rule with the "User has role(s)" condition will crash with the following error:
Error: Call to a member function id() on string in Drupal\rules\Plugin\Condition\UserHasRole->Drupal\rules\Plugin\Condition\{closure}() (line 58 of modules/contrib/rules/src/Plugin/Condition/UserHasRole.php).

In my case, this occurred on Drupal 9.5.4 with Rules 8.x-3.0-alpha7.

Steps to reproduce

  1. Create a rule with the "User has role(s)" condition.
  2. Trigger the rule.
  3. The site will crash with the error message described in the Problem/Motivation.

Proposed resolution

I'll attach a patch to the issue as soon as it's been created.

πŸ› Bug report
Status

Active

Version

4.0

Component

Rules Core

Created by

πŸ‡ΊπŸ‡ΈUnited States jsutta United States

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

Comments & Activities

  • Issue created by @jsutta
  • πŸ‡ΊπŸ‡ΈUnited States jsutta United States

    Attaching patch.

  • Status changed to Postponed: needs info over 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States tr Cascadia

    The issue that fixed this problem was #2800749: Support upcasting entity IDs to full entity contexts β†’ , which made large structural changes. As explained in #3088481: Call to a member function id() on string in SystemMailToUsersOfRole.php β†’ , making a quick fix in the user has role condition like your patch does is not acceptable in any case, because it would only "fix" that one condition and would require similar "fixes" in every other condition and action that supports user roles. That is why we took the extra time and effort to fix the structure rather than make a quick fix.

    Regardless, we have automated tests to ensure the condition works properly, so if you are still seeing a problem I need to you make sure you have the current -dev version installed and I need you to provide an export of a full rule that uses this condition and has the problem. The most likely explanation is that you have a rule that is passing an invalid role id or user object to the condition, but the only way I can help you is if I see the entire rule export so I can see what you've entered for all the values.

    See https://www.drupal.org/docs/contributed-modules/rules-essentials/importi... β†’

  • πŸ‡¬πŸ‡§United Kingdom adam_b

    I think I'm getting the same issue, with a rule I imported from the documentation β†’

    I imported it and changed the role to "administrator". When I run it, a new user is created in the background, but with no role assigned, and the user gets a WSOD.

    I've attached the error message and the exported rule.

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

    What version of Rules are you using?

  • πŸ‡¬πŸ‡§United Kingdom adam_b

    8.x-3.x-dev, with 9.5.4 core

  • Status changed to Active 4 months ago
  • πŸ‡±πŸ‡ΉLithuania vibrasphere

    This is still a problem in the stable 4.0.0 version for Drupal 10.

    Import this rule and try to login, you will get WSOD.

    Refresh the page and you will be logged in.

    Check dblog for more.

    uuid: 4bfe857e-116b-48c0-8c74-d34c649f98c1
    langcode: en
    status: true
    dependencies: {  }
    id: redirect_admin_on_login
    label: 'Redirect admin on login'
    events:
      -
        event_name: rules_user_login
    description: ''
    tags: {  }
    config_version: '3'
    expression:
      id: rules_rule
      uuid: c8b0e41e-57a6-440e-b957-9223634eae69
      weight: 0
      conditions:
        id: rules_and
        uuid: 636a102b-3905-4923-bf33-54bb074c3287
        weight: 0
        conditions:
          -
            id: rules_condition
            uuid: a876dfb4-cbc0-4f4f-84c9-11a8da8d082f
            weight: 0
            condition_id: rules_user_has_role
            negate: false
            context_values:
              roles:
                - account.roles.2
              operation: AND
            context_mapping:
              user: account
            context_processors:
              roles:
                rules_tokens: {  }
              operation:
                rules_tokens: {  }
            provides_mapping: {  }
      actions:
        id: rules_action_set
        uuid: 812cc408-7b71-486b-9459-9abcd46ea294
        weight: 0
        actions:
          -
            id: rules_action
            uuid: 849dca9c-e5af-46cd-9b61-ecfe35625964
            weight: 0
            action_id: rules_page_redirect
            context_values:
              url: /admin/content
            context_mapping: {  }
            context_processors:
              url:
                rules_tokens: {  }
            provides_mapping: {  }
    
  • πŸ‡ΊπŸ‡ΈUnited States tr Cascadia

    I'll try your rule sometime over the weekend probably, but at first glance do you really have a role with a machine id of "account.roles.2"? Because that's not a valid Drupal machine name - periods are not allowed in a machine name. When you export a rule like this for others to test, it is usually best that you simplify it to something that is intended to work on any Drupal site. In this case that would mean changing the role to one that is standard in Drupal and exists on every machine. Likewise, if you rule involves content types, you should use one of the built-in content types so that everyone can use your rule. Etc.

  • πŸ‡±πŸ‡ΉLithuania vibrasphere

    I don't know, it's from data selector when adding condition User has Role, I assumed number was ID for roles or something.

    Like, how do we know which one is default Administrator role? You are not allowed to just type in 'administrator'.

    I do remember back in Drupal 7 there was a dropdown with all roles listed and you just select right one.

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

    The dropdown isn't working in the current version of Rules, which is what makes configuring things harder than it should be. It's too easy to make a mistake or spell something wrong. When we get the dropdown back, then you will only be able to select valid values.

    Your export doesn't indicate that you used the data selector for the role name.

    The Condition has two context variables that are assigned values from the data you enter in that form: user and roles.
    In the export, it shows that the roles variable was set with direct input (it is listed under context_values). In this case, I would expect to see the machine name of the role that you want to check for. Try editing your rule and using direct input to change the role to a valid machine name.

    Direct input is the default input method for the roles variable, and it is here that the dropdown would be useful to give you a selection the available roles so that you wouldn't need to know the machine names and couldn't spell or capitalize anything wrong, for example.

            context_values:
              roles:
                - account.roles.2
              operation: AND
            context_mapping:
              user: account

    The user variable was set using the data selector, because it is listed under context_mapping. That looks fine - the account object is provided by the user login event.

  • πŸ‡±πŸ‡ΉLithuania vibrasphere

    Okay the WSOD is gone since we input 'administrator', but now the rule doesn't trigger? In this scenario if user logged in and has role: administrator it should redirect to given path? But it doesn't. Tested using the super user uid 1. No entries in dblog.

    uuid: 4bfe857e-116b-48c0-8c74-d34c649f98c1
    langcode: en
    status: true
    dependencies: {  }
    id: redirect_admin_on_login
    label: 'Redirect admin on login'
    events:
      -
        event_name: rules_user_login
    description: ''
    tags: {  }
    config_version: '3'
    expression:
      id: rules_rule
      uuid: c8b0e41e-57a6-440e-b957-9223634eae69
      weight: 0
      conditions:
        id: rules_and
        uuid: 636a102b-3905-4923-bf33-54bb074c3287
        weight: 0
        conditions:
          -
            id: rules_condition
            uuid: a876dfb4-cbc0-4f4f-84c9-11a8da8d082f
            weight: 0
            condition_id: rules_user_has_role
            negate: false
            context_values:
              roles:
                - administrator
              operation: AND
            context_mapping:
              user: account
            context_processors:
              roles:
                rules_tokens: {  }
              operation:
                rules_tokens: {  }
            provides_mapping: {  }
      actions:
        id: rules_action_set
        uuid: 812cc408-7b71-486b-9459-9abcd46ea294
        weight: 0
        actions:
          -
            id: rules_action
            uuid: 849dca9c-e5af-46cd-9b61-ecfe35625964
            weight: 0
            action_id: rules_page_redirect
            context_values:
              url: /admin/content
            context_mapping: {  }
            context_processors:
              url:
                rules_tokens: {  }
            provides_mapping: {  }
    
Production build 0.71.5 2024