<p>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).</p>

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

<p>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.</p>

<p><a href="https://craftcms.stackexchange.com/questions/10482/handling-endless-recursion-in-saveentry">Brad mentions</a>  one way around that is to simply update the db directly instead of calling <code>saveUser</code>. Since you're using a custom field, that's a bit harder to do.</p>

<p>Another would be to define a <a href="http://php.net/manual/en/language.variables.scope.php#language.variables.scope.static" rel="nofollow noreferrer"><code>static</code></a> variable and only allow your code to call <code>saveUser</code> once.</p>

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


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

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

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

<p>That's also documented in my <a href="https://craftcms.stackexchange.com/questions/10482/handling-endless-recursion-in-saveentry">original question</a>.</p>

CC BY-SA 3.0
2015-12-05T21:56:10.493Z
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.
Chris Southam
CC BY-SA 3.0
2015-12-05T22:33:22.630Z
I know right? Not obvious enough until it's pointed out ;)
RitterKnight
CC BY-SA 3.0
2015-12-05T21:33:13.033Z
2015-12-05T21:53:10.720Z
2017-04-13T12:51:00.200Z
RitterKnight
<p>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.</p>

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

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

<p><em>talentJobFamily and talentStage are both custom fields.</em></p>

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


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


            craft()-&gt;users-&gt;saveUser($user);
        }
    });
}
</code></pre>

<users><craft-pro>
users.onSaveUser firing multiple times
# users.onSaveUser firing multiple times

(Asked by: username_0 on 2015-12-04)

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);
        }
    });
}

**Tags:** users, craft-pro


---

## 1 answers

### Answer by username_1 on 2015-12-05. Score: 2 | Accepted answer

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.

> **Comments:**
> **username_0**: Cracking answer there, thank you @username_1. 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.  
> **username_1**: I know right? Not obvious enough until it's pointed out ;)  

---

