4

I'm writing a simple project-specific plugin that sends a notification to the site admin when a new user is registered. I have an HTML template that I'd like to use for this.

In my plugin's main class, I have the following function:

public function init()
    {
        parent::init();
        // Events
        craft()->on('users.saveUser', function(Event $event) {
            $user = $event->params['user'];
            $isNewUser = $event->params['isNewUser'];

            if ($isNewUser)
            {
                // Send notification email
                craft()->aeiMember->registrationNotification($user);
            }
        });
    }

which calls a one of my plugin's services, 'registrationNotification'. Here's the code I have for that service:

public function registrationNotification(UserModel $savedUser)
    {
        $user = new \stdClass();

        $user->firstName            = $savedUser->firstName;
        $user->lastName             = $savedUser->lastName;
        $user->email                = $savedUser->email;
        $user->aeiGroups            = $savedUser->aeiGroups;
        $user->phone                = $savedUser->phone;
        $user->mailingAddress       = $savedUser->mailingAddress;
        $user->city                 = $savedUser->city;
        $user->state                = $savedUser->state;
        $user->zip                  = $savedUser->zip;
        $user->country              = $savedUser->country;
        $user->preferredDealer      = $savedUser->preferredDealer;
        $user->dealerAccountNumber  = $savedUser->dealerAccountNumber;
        $user->school               = $savedUser->school;
        $user->expectedGraduationDate = $savedUser->expectedGraduationDate;

        $email = new EmailModel();
        $email->toEmail = '...myemailaddress...';
        $email->subject = 'New User Registration: ' . $user->firstName . ' ' . $user->lastName;
        $email->htmlBody = craft()->templates->render('aeiMember/registration_notification', array(
            'user' => $user,
        ));

        // Send
        if (craft()->email->sendEmail($email))
        {
            return true;
        }
    }

When I submit the registration form, I get the following error: "CDbException: CDbTransaction is inactive and cannot perform commit or roll back operations.". I narrowed down the issue, and if I use a non-HTML email body, everything works fine, so apparently there's an issue with rendering a template at this event.

Here's a link to a Google Doc with the stack trace: https://docs.google.com/document/d/1atFNkktuZQ91hU9QipXYMhOCHNGAavO5qUI_TF5jSeE/edit?usp=sharing

Am I doing something wrong, or is there a workaround to accomplish what I'm after? It seems like it should be pretty simple.

  • 1
    Is your non-HTML email body still accessing all the values of the stdClass object? CDbTransaction is a database class for DB transactions and I can't even begin to understand why this code here is concerned with hitting the database. Do you have devMode on? If so, could you post the stack trace? – Matt Stauffer Jun 24 '14 at 4:05
  • Good point - no, the non-HTML email body wasn't accessing any values. I reviewed the template, and the only variables it is accessing are 'user' and the global 'now'. I do have devMode on, I've edited my question to include a link to the stack trace. – shanecavaliere Jun 24 '14 at 14:59
  • 1
    If you substitute the craft()->templates->render call with some static html, do you get the same error? If you do the template render call and store the contents in a variable (and don't add it as a htmlBody), do you get the same error? – André Elvan Jun 24 '14 at 15:09
  • What's confusing is that the stack trace shows the error on saving the user, which should happen before this is triggered, so I don't know why the email template would affect it. As far as I can tell it hasn't even hit the "'onEndRequest'" yet. If @aelvan's questions don't get you anywhere, you might need to just submit a support request. – Matt Stauffer Jun 24 '14 at 15:13
  • 2
    What does the registration_notification template look like? Something is triggering a call to UsersController->saveUser when calling render() and I suspect that's something in your template code? – Brad Bell Jun 24 '14 at 15:37
5

The issue turned out to be the result of a variable name mistake on my part. I had typed in an incorrect variable name in the email template. I actually still don't really understand what that has to do with a database transaction, though.

EDIT: If anyone else is running into a similar issue, I've found a way to get a more useful error message, as opposed to the "CDbTransaction is inactive" message, which doesn't help much. If you go to craft/app/services/UsersService.php, and comment out line 311 ("$transaction->rollback();"), then Yii won't give you the CDbTransaction error before Craft has a chance to tell you its more helpful error. This should give you a better idea of what you're doing wrong. Obviously, don't forget to un-comment that line after you've fixed your issue.

  • 1
    It was probably triggering some lazy-loading method for users which was, in-turn, making a call to the database to attempt to retrieve data. – Brad Bell Jun 24 '14 at 21:36
  • Very helpful EDIT tip. The line is #320 now. (Craft 2.6.2780) – Marion Newlevant Apr 19 '16 at 23:59
1

It throws the error, since it fires the event in the transaction try-catch, and Twig was throwing the exception. In the catch block then it tried to execute the rollback.

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.