2

When a user saves a front-end form, and has a custom field with a set value, I want to send an email - and set another field on the users profile to indicate a mail has been sent, so that if the form is saved again, another email will not be sent.

To do this I have a small plugin:

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

        if($consentGiven == 'yes' and $notificationAlreadySent != '1') {
            ... SEND EMAIL CODE ...

            // now set the notificationAlreadySent to '1' so we dont get in this conditional next time
                $userModel = new UserModel();

                // why we need to manually read these to write the same values I don't know
                $userModel->id        = $user->id;
                $userModel->username  = $user->username;
                $userModel->firstName = $user->firstName;
                $userModel->lastName  = $user->lastName;
                $userModel->email     = $user->email;

                // update the one field we actually wanted to update in the first place
                $userModel->getContent()->setAttributes(array(
                    'notificationAlreadySent' => '1'
                ));

                // Actually save it
                craft()->users->saveUser($userModel);
        }
    }
});

Problem: This ends up in a loop because it's watching the onSaveUser event, and inside that event it's calling saveUser. I figure I actually need the onBeforeSaveUser event, and I need to tweak the value of that field there so that it'll "just work" once it gets to the saveUser action.

That being the case I've tried this instead...

public function init() {
    craft()->on('users.onBeforeSaveUser', function(Event $event) {
        $user = $event->params['user'];
        $consentGiven = craft()->request->getPost('fields.consentGiven', 'no');
        $notificationAlreadySent = $user->notificationAlreadySent;

        if($consentGiven == 'yes' and $notificationAlreadySent != '1') {
            ... SEND EMAIL CODE ...

            // now set the notificationAlreadySent to '1' so we dont get in this conditional next time
                $user->fields['notificationAlreadySent'] = '1';
        }
    }
});

New problem: The syntax $user->fields['notificationAlreadySent'] = '1'; doesn't appear to be correct, and I can not work out how to reference that property...

5

Solution:

Instead of:

$user->fields['notificationAlreadySent'] = '1';

Use

$user->getContent()->setAttributes(array(
    'notificationAlreadySent' => 1
));

Of note: I find this sort of thing extremely hard to research. I know what I want to do (edit the value of a field in an event via the onBefore listener) but documentation on how to do that seems non-existent. I keep finding this sort of problem with developing Craft plugins - that unless you know the internals, you're really hard pressed to even articulate what you're wanting to search for in order to find a solution.

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.