<p>Here's another way to avoid the "saveEntry" infinite loop. I like to have a method in a service class that my plugin that can reuse over and over again to update entry values. As you can see, we avoid unnecessary statics and clutter in the plugin init() method.
The main thing to point out is the use of "saveElement()" instead of "saveEntry()" which is the key to not triggering the saveEntry event endlessly.</p>

<p>From the main plugin file:</p>

<pre><code>/**
 * Plugin Init
 */
public function init()
{
    parent::init();

    // triggers
    craft()-&gt;on('entries.saveEntry', array($this, '_processUsersToNotify'));
}

/**
 * Process Users To Notify
 *
 * @param Event $event
 */
public function _processUsersToNotify(Event $event)
{
    $entry = $event-&gt;params['entry']-&gt;attributes;

    $entryData = [
        'fieldSlug1' =&gt; 'lorem ipsum',
        'usersToNotify' =&gt; [1,2,3,4,5],
    ];

    // using a service method (replace pluginName/serviceName accordingly)
    craft()-&gt;pluginName_serviceName-&gt;updateEntry($entry['id'], $entryData);
}
</code></pre>

<p>Then in your service file:</p>

<pre><code>/**
 * Update Entry Data
 */
public function updateEntry($entryId, $data)
{
    // placeholder for phase 2 feature
    $entry = craft()-&gt;entries-&gt;getEntryById($entryId);

    // set attrs
    $entry-&gt;getContent()-&gt;setAttributes($data);

    if ($entry-&gt;validate())
    {
        craft()-&gt;elements-&gt;saveElement($entry);
    }
    else
    {
        return $entry-&gt;getErrors();
    }

    return true;
}
</code></pre>

CC BY-SA 3.0
2016-10-03T18:19:33.017Z
2016-10-03T18:19:33.017Z
Jarrett Barnett
<p>You've created an endless loop with calling <code>saveEntry</code> within the <code>entries.saveEntry</code> event listener. You can fix it with implementing a static variable.</p>

<pre><code>craft()-&gt;on('entries.saveEntry', function(Event $event) {
    static $recursionLevel = 0;

    if ($recursionLevel == 0) {
        $recursionLevel++;

        // `saveEntry` in `addAnotherUserToNotify` triggers another
        // `entries.saveEntry` event
    }
});
</code></pre>

CC BY-SA 3.0
2016-03-30T08:56:55.673Z
2016-03-30T08:56:55.673Z
carlcs
<p>I'm building a plugin which needs to add users to a users-type field when they edit the entry on the front-end. It works well when the post is created, adding the original author to the field, and again when the same user edits the post. However, when another user edits the post everything comes to a standstill for a minute and users are taken not to the landing page, but to a page containing nothing other than a "1". Checking the back-end, it has added the second user to the field, though.</p>

<p>Can anyone suggest to me from the code below why adding a second (haven't tested any more than that yet) user brings things the server to its knees?</p>

<pre><code>public function init()
{
    parent::init();

    // ON SAVE ENTRY
    craft()-&gt;on('entries.saveEntry', function(Event $event) {

        $entry = $event-&gt;params['entry'];
        $user = craft()-&gt;userSession-&gt;getUser();
        $notifyMe = craft()-&gt;request-&gt;getPost('notifyme');          

        // CHECK THIS IS THE FORUM SECTION
        if ($entry-&gt;sectionId == 16) {
            craft()-&gt;notifier-&gt;addAnotherUserToNotify($entry, $user, $notifyMe);
        }           
    });
}
</code></pre>

<p>And here is the function:</p>

<pre><code>// ADD ANOTHER USER TO A POST'S NOTIFICATION LIST
public function addAnotherUserToNotify($entry, $user, $notifyMe) 
{
    if ($notifyMe == "yes") {

        // GET IDs OF USERS ALREADY LISTED TO BE NOTIFIED
        $usersToNotify = $entry-&gt;usersToNotify-&gt;ids();
        if ( ! in_array( $user-&gt;id, $usersToNotify ) ) {
            // ADD THE CURRENT USER TO THE ARRAY OF USERS TO BE NOTIFIED
            $usersToNotify[] = $user-&gt;id;
        }           

        // UPDATE THE ENTRY'S FIELD WITH THIS UPDATED ARRAY
        $entry-&gt;getContent()-&gt;setAttribute('usersToNotify', $usersToNotify);

        // SAVE ENTRY
        craft()-&gt;entries-&gt;saveEntry($entry);

    }

}
</code></pre>

<p>The code is inspired by <a href="https://craftcms.stackexchange.com/questions/13032/update-user-field-type-for-entry-in-plugin">Update User &quot;Field Type&quot; for Entry in Plugin</a></p>

CC BY-SA 3.0
2016-03-30T08:38:16.637Z
Can you post the (relevant) code from that `addAnotherUserToNotify` method, my guess is you've created an endless loop with calling `saveEntry` within the `entries.saveEntry` event listener.
carlcs
CC BY-SA 3.0
2016-03-30T08:44:31.050Z
Sorry, I thought I'd added that but lost it while faffing with the formatting. Added.
Clive Portman
<plugin-development><users>
Adding second user to user field in plugin brings server to its knees
# Adding second user to user field in plugin brings server to its knees

(Asked by: username_0 on 2016-03-30)

I'm building a plugin which needs to add users to a users-type field when they edit the entry on the front-end. It works well when the post is created, adding the original author to the field, and again when the same user edits the post. However, when another user edits the post everything comes to a standstill for a minute and users are taken not to the landing page, but to a page containing nothing other than a "1". Checking the back-end, it has added the second user to the field, though.
Can anyone suggest to me from the code below why adding a second (haven't tested any more than that yet) user brings things the server to its knees?
public function init()
{
    parent::init();

    // ON SAVE ENTRY
    craft()->on('entries.saveEntry', function(Event $event) {

        $entry = $event->params['entry'];
        $user = craft()->userSession->getUser();
        $notifyMe = craft()->request->getPost('notifyme');          

        // CHECK THIS IS THE FORUM SECTION
        if ($entry->sectionId == 16) {
            craft()->notifier->addAnotherUserToNotify($entry, $user, $notifyMe);
        }           
    });
}

And here is the function:
// ADD ANOTHER USER TO A POST'S NOTIFICATION LIST
public function addAnotherUserToNotify($entry, $user, $notifyMe) 
{
    if ($notifyMe == "yes") {

        // GET IDs OF USERS ALREADY LISTED TO BE NOTIFIED
        $usersToNotify = $entry->usersToNotify->ids();
        if ( ! in_array( $user->id, $usersToNotify ) ) {
            // ADD THE CURRENT USER TO THE ARRAY OF USERS TO BE NOTIFIED
            $usersToNotify[] = $user->id;
        }           

        // UPDATE THE ENTRY'S FIELD WITH THIS UPDATED ARRAY
        $entry->getContent()->setAttribute('usersToNotify', $usersToNotify);

        // SAVE ENTRY
        craft()->entries->saveEntry($entry);

    }

}

The code is inspired by Update User "Field Type" for Entry in Plugin

**Tags:** plugin-development, users

> **Comments:**
> **username_1**: Can you post the (relevant) code from that `addAnotherUserToNotify` method, my guess is you've created an endless loop with calling `saveEntry` within the `entries.saveEntry` event listener.  
> **username_0**: Sorry, I thought I'd added that but lost it while faffing with the formatting. Added.  

---

## 2 answers

### Answer by username_1 on 2016-03-30. Score: 5 | Accepted answer

You've created an endless loop with calling saveEntry within the entries.saveEntry event listener. You can fix it with implementing a static variable.
craft()->on('entries.saveEntry', function(Event $event) {
    static $recursionLevel = 0;

    if ($recursionLevel == 0) {
        $recursionLevel++;

        // `saveEntry` in `addAnotherUserToNotify` triggers another
        // `entries.saveEntry` event
    }
});


---

### Answer by username_2 on 2016-10-03. Score: 1

Here's another way to avoid the "saveEntry" infinite loop. I like to have a method in a service class that my plugin that can reuse over and over again to update entry values. As you can see, we avoid unnecessary statics and clutter in the plugin init() method.
The main thing to point out is the use of "saveElement()" instead of "saveEntry()" which is the key to not triggering the saveEntry event endlessly.
From the main plugin file:
/**
 * Plugin Init
 */
public function init()
{
    parent::init();

    // triggers
    craft()->on('entries.saveEntry', array($this, '_processUsersToNotify'));
}

/**
 * Process Users To Notify
 *
 * @param Event $event
 */
public function _processUsersToNotify(Event $event)
{
    $entry = $event->params['entry']->attributes;

    $entryData = [
        'fieldSlug1' => 'lorem ipsum',
        'usersToNotify' => [1,2,3,4,5],
    ];

    // using a service method (replace pluginName/serviceName accordingly)
    craft()->pluginName_serviceName->updateEntry($entry['id'], $entryData);
}

Then in your service file:
/**
 * Update Entry Data
 */
public function updateEntry($entryId, $data)
{
    // placeholder for phase 2 feature
    $entry = craft()->entries->getEntryById($entryId);

    // set attrs
    $entry->getContent()->setAttributes($data);

    if ($entry->validate())
    {
        craft()->elements->saveElement($entry);
    }
    else
    {
        return $entry->getErrors();
    }

    return true;
}


---

