Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.x]: Attach a User Element to another User via user registration frontend form with conditions #12283

Closed
masiorama opened this issue Nov 9, 2022 · 11 comments

Comments

@masiorama
Copy link

What happened?

Description

I attached to user fields a field which relate it to another group of user, let's call the first one "client" and the last one "agent".
It seems to me that it is possibile to attach a User element via frontend form creating an hidden input like this:

{{ hiddenInput('fields[associatedAgent]', associatedAgent.id) }}

It works without restrictions, but it stops working if you add a condition on user field associatedAgent conditional field, like 'show this field only on user of group clients.

Clients is the default group on user registration.

Here you can find more details and screens: https://craftcms.stackexchange.com/questions/40075/attach-a-user-element-to-another-user-via-user-registration-frontend-form

Steps to reproduce

  1. create "agents" and "clients" user groups on the panel
  2. set "clients" user group as default on registration
  3. create an associatedAgent field which can be populated with "agents" users only
  4. associate the field to user fields section
  5. add condition to show that field only on "clients" user

Expected behavior

The related user agent forced by frontend registration form is associated.

Actual behavior

The related user agent forced by frontend registration form is not associated.

Craft CMS version

4.3.1

PHP version

8.2

Operating system and version

Win 10

Database type and version

Mysql 5.7

Image driver and version

No response

Installed plugins and versions

  • Commerce: 4.2.2
  • Navigation: 2.0.10
  • Redactor: 3.0.2
  • Wheelform: 3.1.3
@brandonkelly
Copy link
Member

brandonkelly commented Nov 10, 2022

This is expected behavior. User conditions are enforced for all form submissions, regardless of whether the submission happened on the front end or back end.

@masiorama
Copy link
Author

masiorama commented Nov 10, 2022

Hi @brandonkelly thanks for your reply. I don't understand completely: I have different behavior in those 2 scenarios. On frontend, with the active rule, the saving fails, while on backend, with the active rule, it works saving the relation... maybe I explained myself badly...

update: I'm discussing the matter with @mmikkel on Craft CMS Stack exchange, and he suggested that it could be that on the frontend the saving of the agent does not work because the system doesn't know yet that the created user has to be in the "client" group, even if it is the default group... it rings the bell, but I'm reaching out to you just to be sure this is the problem.

Just in case, how do you suggest me to achieve my goal, is there a specific event I could leverage on before the associatedAgent data is purged before saving?

Thanks for any further help!

@brandonkelly
Copy link
Member

Sorry for the delay. I think I may have been confused a bit – can you post a screenshot of the condition you added?

@masiorama
Copy link
Author

Hello @brandonkelly , here the screenshot you requested.

ab7oO

More details on craft stackexchange: https://craftcms.stackexchange.com/questions/40075/attach-a-user-element-to-another-user-via-user-registration-frontend-form

@i-just
Copy link
Contributor

i-just commented Jan 10, 2023

Thanks for more info on this. This happens because of the order of actions when creating a new user. First, all data is validated and saved, and at the end, the user is assigned to a default group (in your case: clients). Only once the user is assigned to a default group is the conditional met. But at that point, the data was already processed, with the conditional deemed not to have been met. (The same thing happens when you create a new user via the control panel, only after you successfully save for the first time do conditional fields relying on the user group start showing.)

You can achieve what you’re after with custom code if you, e.g. hook up to the craft\services\Users::EVENT_AFTER_ASSIGN_USER_TO_DEFAULT_GROUP event.

We’ll talk about this internally and update this issue if we come up with anything meaningful.

@masiorama
Copy link
Author

Thank you very much, I will investigate on the event you suggested. Thanks again for the support!

@brandonkelly
Copy link
Member

This is fixed now for the next release, via #12544. Thanks for reporting!

@brandonkelly
Copy link
Member

Craft 4.3.7 has been released with that fix.

@ryssbowh
Copy link

ryssbowh commented Sep 3, 2023

I've had the same problem assigning a user to a group depending on some conditions :

I have 2 groups with each their own conditional fields and each can use the public registration (I can't use the "Default User Group" setting), the user would not be populated/validated properly.

My solution was to pass the user group in the registration request and use the following events :

if (\Craft::$app->request->isSiteRequest) {
    Event::on(User::class, User::EVENT_INIT, function (Event $event) {
        if (!$event->sender->id) {
            $group = \Craft::$app->userGroups->getGroupByHandle(\Craft::$app->request->getBodyParam('group'));
            $user->setGroups([$group]);
        }
    });
    Event::on(Elements::class, Elements::EVENT_AFTER_SAVE_ELEMENT, function (Event $event) {
        if ($event->element instanceof User and $event->isNew) {
            $group = \Craft::$app->userGroups->getGroupByHandle(\Craft::$app->request->getBodyParam('group'));
            \Craft::$app->getUsers()->assignUserToGroups($event->element->id, [$group->id]);
        }
    });
}

Obviously it's not great since requests can be forged.

It would probably be useful to add an event before the user is populated with the post fields on the registration process ? Maybe only if the "Default User Group" is not set ? https://github.com/craftcms/cms/blob/develop/src/controllers/UsersController.php#L1437

@brandonkelly
Copy link
Member

brandonkelly commented Sep 10, 2023

@ryssbowh Good suggestion. I just added a new craft\services\Users::getDefaultUserGroups() method for the next release, which centrally defines the default user groups for a given user.

It fires an EVENT_DEFINE_DEFAULT_USER_GROUPS event that gives plugins an opportunity to customize the groups:

use craft\base\Event;
use craft\events\DefineUserGroupsEvent;
use craft\services\Users;

Event::on(
    Users::class,
    Users::EVENT_DEFINE_DEFAULT_USER_GROUPS,
    function(DefineUserGroupsEvent $event) {
        $group = Craft::$app->userGroups->getGroupByHandle('myGroup');
        $event->userGroups[] = $group;
    }
);

@brandonkelly
Copy link
Member

Craft 4.5.4 is out with that new event.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants