1

Could anyone help me with this one? I have a custom plugin which needs to update a user's custom field with a particular value if they've filled out something on the registration form.

I believe the code below would work but it's running 44 times which is causing a nesting level error with xdebug.

Could anyone tell me why it would be running 44 times on a simple /users/saveUser post request with the below hook?

talentJobFamily and talentStage are both custom fields.

public function init()
{
    craft()->on('users.onSaveUser', function (Event $event)
    {
        $user = $event->params['user'];


        if ($user->talentJobFamily->value != '') {
            $user->getContent()->setAttributes([
                'talentStage' => 'engage',
            ]);


            craft()->users->saveUser($user);
        }
    });
}
2

This burned me awhile back. As I understand it, your code is not just running 44 times, it's actually running an endless loop... until it blows up (and likely runs out of memory).

Basically when you attach onto onSaveUser and then save again using SaveUser, Craft is going to give other plugins—that also latch onto the onSaveUserevent—a shot at manipulating the data you just saved.

So the wrinkle there is Craft is going to call your code again, resulting in the endless loop. Basically you need a way to break the loop.

Brad mentions one way around that is to simply update the db directly instead of calling saveUser. Since you're using a custom field, that's a bit harder to do.

Another would be to define a static variable and only allow your code to call saveUser once.

public function init()
{
    craft()->on('users.onSaveUser', function (Event $event)
    {
        $user = $event->params['user'];


        if ($user->talentJobFamily->value != '') {
            $user->getContent()->setAttributes([
                'talentStage' => 'engage',
            ]);

            static $recursionLevel = 0; // is set only once

            if ($recursionLevel == 0) 
            {
                $recursionLevel++; // saveUser only gets called once
                craft()->users->saveUser($user);
            }
        }
    });
}

That's also documented in my original question.

2
  • Cracking answer there, thank you @RitterKnight. Must admit outside of being knee-deep in the code that's painfully obvious now! I'll work on a fix either way, static variable seems the simplest. Dec 5 '15 at 21:56
  • 1
    I know right? Not obvious enough until it's pointed out ;) Dec 5 '15 at 22:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.