Problem/Motivation

When editing a user as a non administrator user (Role Delegation module is required), the roles are not processed correctly on save because `$values['roles']` should be an array of role names and Role Delegation has the `target_id` property. Also, we are not processing all the roles, just the last one.

Steps to reproduce

  • Create three new custom roles: `roledelegationassign`, `subscriber` and `premium`
  • Enable Role Delegation module
  • Go to permissions page (Role Delegation section): give the permissions "Assign subscriber role" and "Assign premium role" to the `roledelegationassign` role
  • Create a user with the new `roledelegationassign` role
  • Login as the new user
  • Create a new user
  • Assign the user the `subscriber` and `premium` roles and assign an expiration of "2 months" on both
  • Save the user
  • Role expire won't be saved for both roles

Proposed resolution

Fix the code as seen in the first enclosed patch.

Remaining tasks

Create a MR against 4.x branch.

Original report by pearls

I get this error with Drupal 10.3.x and Role Expire 3.x versions.
Any idea, please?

TypeError: array_diff(): Argument #2 must be of type array, null given in array_diff() (line 194 of /var/www/html/mysite/web/modules/contrib/role_expire/role_expire.module).
#0 /var/www/html/mysite/web/modules/contrib/role_expire/role_expire.module(194): array_diff()
#1 [internal function]: role_expire_user_form_submit()
#2 /var/www/html/mysite/web/core/lib/Drupal/Core/Form/FormSubmitter.php(129): call_user_func_array()
#3 /var/www/html/mysite/web/core/lib/Drupal/Core/Form/FormSubmitter.php(67): Drupal\Core\Form\FormSubmitter->executeSubmitHandlers()
#4 /var/www/html/mysite/web/core/lib/Drupal/Core/Form/FormBuilder.php(597): Drupal\Core\Form\FormSubmitter->doSubmitForm()
#5 /var/www/html/mysite/web/core/lib/Drupal/Core/Form/FormBuilder.php(326): Drupal\Core\Form\FormBuilder->processForm()
#6 /var/www/html/mysite/web/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\Core\Form\FormBuilder->buildForm()
#7 [internal function]: Drupal\Core\Controller\FormController->getContentResult()
#8 /var/www/html/mysite/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array()
#9 /var/www/html/mysite/web/core/lib/Drupal/Core/Render/Renderer.php(638): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#10 /var/www/html/mysite/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(121): Drupal\Core\Render\Renderer->executeInRenderContext()
#11 /var/www/html/mysite/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext()
#12 /var/www/html/mysite/vendor/symfony/http-kernel/HttpKernel.php(181): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#13 /var/www/html/mysite/vendor/symfony/http-kernel/HttpKernel.php(76): Symfony\Component\HttpKernel\HttpKernel->handleRaw()
#14 /var/www/html/mysite/web/core/lib/Drupal/Core/StackMiddleware/Session.php(53): Symfony\Component\HttpKernel\HttpKernel->handle()
#15 /var/www/html/mysite/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle()
#16 /var/www/html/mysite/web/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle()
#17 /var/www/html/mysite/web/core/modules/big_pipe/src/StackMiddleware/ContentLength.php(32): Drupal\Core\StackMiddleware\ContentLength->handle()
#18 /var/www/html/mysite/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\big_pipe\StackMiddleware\ContentLength->handle()
#19 /var/www/html/mysite/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass()
#20 /var/www/html/mysite/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle()
#21 /var/www/html/mysite/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle()
#22 /var/www/html/mysite/web/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle()
#23 /var/www/html/mysite/web/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle()
#24 /var/www/html/mysite/web/core/lib/Drupal/Core/DrupalKernel.php(741): Drupal\Core\StackMiddleware\StackedHttpKernel->handle()
#25 /var/www/html/mysite/web/index.php(19): Drupal\Core\DrupalKernel->handle()
#26 {main}
Command icon 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

pearls created an issue. See original summary.

sarwan_verma’s picture

Status: Active » Needs review
StatusFileSize
new2.54 KB

Hi,

I have resolved the 'array_diff(): Argument' issue and attached the patch.
Please review and verify.

Thanks.

rcodina’s picture

Status: Needs review » Postponed (maintainer needs more info)

I need detailed steps to reproduce the problem.

pearls’s picture

Hi @rcodina

When I changed some fields (for example first or last name - custom text field), the TypeError warning mentioned in the previous post appeared, even though I did not touch the role expiration date.
This warning is gone after the patch .#2

pearls’s picture

StatusFileSize
new305.22 KB
new325.84 KB

Thanks @sarwan_verma,
Patch is ok, it worked, the previous warning is gone. But just so you know, there are two php warnings in the log records. I don't know if it is related to the previous problem or the patch. But , it was one time warning. These two warnings did not appear in other changes.
Just FYI.

rcodina’s picture

Version: 3.x-dev » 4.x-dev
Issue summary: View changes
Status: Postponed (maintainer needs more info) » Needs work

@pearls I recommend to use the latest 4.0.0 version.

@sarwan_verma Thanks for the patch. Notice branch 3.x won't receive more updates.

rcodina’s picture

Title: TypeError: array_diff(): Argument #2 must be of type array » TypeError: array_diff(): Argument #2 must be of type array when editing a user with Role Delegation
Status: Needs work » Needs review

@pearls Are you using Role Delegation module?

Please test Role Expire 4.0.0 version with patch of the MR:

https://git.drupalcode.org/project/role_expire/-/merge_requests/15.patch

rcodina’s picture

Thanks to all for using this module and for the feedback.

pearls’s picture

Hi rcodina ,
I use Role Delegation. Now I noticed a similar issue I had before with the Administer Users by Role module and Role expiration.
Anyway.
I tested Version 4. There's no TypeError: array_diff() ... issue mentioned before.
15.patch (#8) worked without previous issue. Thanks for your effort.

FYI :
Normally ,I don't use rules module. I prefer to use ECA. I hope there will be support for it :)
Anyway There's no problem with rules v4 and role expire v4.
Lots of people use rules 8.x-3. And I tested with it. But some upgrade issues happened with Rules v 8.x-3 when I tested. It was a bit hard to upgrade to role expire v4. There were some problems with rules, role_expire_rules. So I completely uninstalled role expire and installed with a new config.I'm not sure everyone can uninstall-reinstall it if they have lots of role expire records.

Below is the log I captured when I tried to upgrade role expire from 3.02 to V4 and update the site database with Rules v 8.x-3 .

Drupal\Component\Plugin\Exception\PluginNotFoundException: The "request_path" plugin does not exist. Valid plugin IDs for Drupal\rules\Core\ConditionManager are: context, request_domain, request_path_exclusion, context_all, view_inclusion, user_status, http_status_code, rules_node_is_sticky, rules_entity_field_access, rules_user_is_blocked, rules_list_contains, rules_path_alias_exists, rules_entity_is_new, rules_data_is_empty, rules_data_comparison, rules_entity_has_field, rules_user_has_role, rules_node_is_published, rules_entity_is_of_type, rules_node_is_of_type, rules_path_has_alias, rules_list_count_is, rules_node_is_promoted, rules_text_comparison, rules_entity_is_of_bundle in Drupal\Core\Plugin\DefaultPluginManager->doGetDefinition() (line 53 of /var/www/html/d10test/web/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryTrait.php).
rcodina’s picture

Title: TypeError: array_diff(): Argument #2 must be of type array when editing a user with Role Delegation » Wrong handling of roles when editing a user with Role Delegation enabled

@pearls With Role Expire 4.0.0 you may not see the error but the handling of roles while in combination with Role Delegation is wrong. So please, use the patch to avoid further issues.

When updating module or core make sure you:

drush cr
drush updb -y
drush cex -y

So all `hook_update` get executed and changes in configuration get stored.

Thanks for the feedback!

rcodina’s picture

Issue summary: View changes

@pearls Follow the ECA integration progess on #3362875: Provide ECA integration

rcodina’s picture

Issue summary: View changes
rcodina’s picture

Issue summary: View changes
rcodina’s picture

The issue description now has the description of the problem and detailed steps to reproduce it.

  • rcodina committed 124c686b on 4.x
    Issue #3467601 by rcodina, sarwan_verma, pearls:  Wrong handling of...
rcodina’s picture

Status: Needs review » Fixed

Thanks to all!

rcodina’s picture

Issue summary: View changes

The release 4.0.1 contains this fix.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.