Sending Custom Emails in Moodle Using the email_to_user() Function

You can send custom emails from within Moodle using PHP using your own forms using the email_to_user() function. By the way, did you know that Moodle actually uses the open source PHPMailer behind the scenes?

A typical call to Moodle's email_to_user() function would look like:

email_to_user($toUser, $fromUser, $subject, $messageText, $messageHtml, '', '', true);

This is a very simple version of a very powerful function. For more information about the email_to_user() function, take a look at the source code for function email_to_user in Moodle's /lib/moodlelib.php.

If you wanted to also include an attachment, you would need to also specify the path to the file to attach as well as give it a file name in the 6th and 7th parameter. The call to email_to_user() should look like this:

email_to_user($toUser, $fromUser, $subject, $messageText, $messageHtml, $completeFilePath, $nameOfFile, true);

Tips for Using email_to_user()

  1. $toUser and $fromUser must be Moodle user objects, not email addresses. The stdClass object must contain a minimum of the following:
    • $emailuser->email: Email address
    • $emailuser->firstname: You can put both first and last name in this field.
    • $emailuser->lastname
    • $emailuser->maildisplay = true;
    • $emailuser->mailformat = 1; // 0 (zero) text-only emails, 1 (one) for HTML/Text emails.
    • $emailuser->id: Moodle User ID. If it is for someone who is not a Moodle user, use an invalid ID like -99.
    • $emailuser->firstnamephonetic
    • $emailuser->lastnamephonetic
    • $emailuser->middlename
    • $emailuser->alternatename
    • Except for those fields above that have a description beside them, the rest of the fields can be set to an empty string if you don't have the information available.
  2. You can convert your HTML message into plain text using:
    $messagetext = html_to_text($messagehtml);
  3. You can get the configured support user information using the following two variables:
    • $CFG->supportemail
    • $CFG->supportname
  4. If you want the email to come from, set the true parameter to  false .

Be sure to always use Moodle filters to clean any user entered information before submitting it in an email including email addresses, subject, message or you will be just asking for trouble.

Enabling Email Debugging in Moodle

When developing email support in your Moodle plugin, you can make your life a whole lot easier by enabling email debugging however this should only be done in a development environment. The settings are all in the same place you would normally go to put Moodle debugging in DEVELOPER mode. Simply complete the following steps:

  1. Click Site Administration > Advanced Features > Development > Debugging
  2. Set Debug messages to DEVELOPER: extra Moodle debug messages for developers
  3. Check the Display debug messages box.
  4. Check the Debug email sending box.
  5. Click Save changes at the bottom of the page.

Don't forget to go back and disable these settings when you are done debugging.


Sending Custom Emails in Moodle Using the email_to_user() Function — 18 Comments

  1. Your typical email_to_user() example has 8 parameters:
    email_to_user($toUser, $fromUser, $subject, $messageText, $messageHtml, “, “, true);
    My email_to_user() function has 5:
    email_to_user(get_user_for_email($p->email, $p->name), get_user_for_email_from(),
    $subject, “”, $report_html);
    does it have to be 8 with ‘true’ at the last? i added all the minimum required values for the user-object, still doesn’ work

    I would appreciate your help

    • Hi Will,

      Not at all. Many of the function’s parameters have default values if they are not specified. Only the first 4 are actually required. The catch is that, if you need to specify the 6th parameter, you need to included the previous 5.

      email_to_user($user, $from, $subject, $messagetext, $messagehtml=”, $attachment=”, $attachname=”, $usetrueaddress=true, $replyto=”, $replytoname=”, $wordwrapwidth=79)

      The email_to_user function returns true if mail was sent OK and false if there was an error.

      From what I can see, your 3rd to 5th parameters are fine. However it would be interesting to find out what the get_user_for_email() and get_user_for_email_from() functions are returning. I believe that is where you will uncover the problem.

  2. Hi,
    I am unable to send images in emails such as logos. It’s showing image path only. How can I imbeded images. I am using Tyne MCE editor for sending a mail.

    • Hi Nidhi,

      Thanks for the great question. First:

      1) Make sure that $emailuser->mailformat = 1
      2) Make sure links to your images are in the format <img src="http..." alt="CompanyName Logo" />

      Note: Gmail and some others may not display the images by default so always make sure that your images include alternate text.

      If you want to actually include embed the image itself, will need to create multipart mime encoded messages might be more complicated. Keeping in mind that Moodle uses the classic lib/phpmailer/class.phpmailer.php email sending library, you might be able to use this to your advantage. Haven’t tried myself but apparently if you specify the real path to the file on your webserver, like <img src="/var/www/moodle/media/logo.png" alt="MyCompanyName Logo" />, I’ve heard that PHPMailer will automatically embed the image for you and replace the tag with <img src="cid:logo.png" alt="MyCompanyName Logo" />. If that doesn’t work for you, the addEmbeddedImage PHPMailer function may be of use to you.

      The nice thing about embedding the logo by reference is that, if you ever update the logo on your server, it will automatically get updated in email as well. If you have a copy of the logo just for emails, you will also be able to see how often emails containing your logo are open by using server log analytics. On the down side, if you ever delete the logo from your server or you change the URL of your website, it will no longer show up in the emails either so make sure you plan to support the location of the logo well into the future.

      Hope this helps,


      • Hello,
        Can PHPMailer be used in conjunction with email_to_user() to embed images in emails? If so, could you give a code snippet for example?
        Thank you

        • Hi Loocarius,

          There is actually a whole discussion on this topic in the Moodle forums. If, by embedded, you simply mean that the images should appear in your email, you could probably achieve this by including an <img src=”…”> tag in the body of your email message. The images would only be visible if the recipient’s computer displaying the message while connected to the Web. For most people, that could be enough. One important note: Your img tags should include ALT text if they contain information. Otherwise, the information will not be visible when images are not displayed – which is the default for popular services gmail and many smartphone users.

          If on the other hand, you actually want the image to be included with the email message so that it is visible even when not connected to the Internet, this would get more complicated as it would involve creating a multi-part mime message in order to include both the content and each of the images.

          Hope this helps.

          Best regards,


    • Thanks for the great question Andres. The good news is that there is a method to do this called addBCC($address, $name = ”). It returns true on success or false if you’ve added a duplicate address. The bad news is that support for this isn’t built into the email_to_user() function. Depending on what you are trying to accomplish, you may need to modify the core code of the email_to_user() function.

      It might be possible to trick the function’s To field without modifying core code by appending a CRLF followed by to the target’s email address of the user object before calling the email_to_user() function. This is just theoretical and you would have to try this as there might be some email address validation going on which would fail as a result of the modified “TO:” address. Naturally you would not update the database with the modified address so all this would be temporary. It’s not the way Moodle is supposed to work but, with a little luck, it might meet your needs. You’ll want to read up on RFC 2822 for details on how to make this modification.

      While I don’t usually recommend it, if you don’t mind modifying Moodle core code, you may be interested in taking a look at a solution by Patrick Pollet posted a few years back in the Moodle forums. Although the solution was for Moodle 1.9 at the time, I looked it over and believe that it could be applied to more modern versions of Moodle in very much the same way. Just remember to always re-patch Moodle after upgrading to a new version or installing a new site.

      Last but not least, you could always bypass the email_to_user() function completely and use PHPMailer. email_to_user is just a wrapper for PHPMailer. Personally I prefer to find a solution which makes use of Moodle API calls whenever possible to future proof. Though unlikely, you never know when Moodle will decide to replace PHPMailer with some other library that would result in your code failing. If your intention is to BCC every email sent out by Moodle, you should explore one of the above solution in order to meet your requirements.

      Hope something in all of this helps.

      Best regards,

      Michael Milette

  3. hi,

    I’m getting a ‘Can not send email to null user’ even if user/user id does have a value.. any advice?

    Warm regards,

    • Hi Cib,

      Thank you for the great question. It sound like you might have skipped the step of creating a temporary Moodle user as mentioned in step 1 under “Tips for Using email_to_user()”. The email_to_user() function doesn’t accept just a name or email address for its parameters. The key to getting it to send email to anyone involves creating enough of a stdClass object so that you can trick Moodle into thinking it is one of its users. You don’t have to actually create a real Moodle user in the database, just a stdClass object. You will need to do this for both the $fromUser and $toUser parameters.

      You can see a working example of this by taking a look at the code for my open source Moodle eMail Test plugin . It is compatible with Moodle as far back as Moodle 2.5 right up to the latest Moodle 3.2 so I am absolutely certain that this technique will work for you if done right.

      Hope this helps. If you need more help, I would be happy to offer you my services. Feel free to contact me at

      Warm regards,


    • Hi Sirisha,

      Great question. Thanks for asking. To include an attachment, you would also need to specify the path to the file you want to attach as well as give it a filename in the 6th and 7th parameter. The call to email_to_user() should look like this:

      email_to_user($toUser, $fromUser, $subject, $messageText, $messageHtml, $completeFilePath, $nameOfFile, true);

      If you are generating the file but don’t want to keep, you will need to first save it in a temporary location, send the email and then delete it.

      Hope this helps. Best regards,

      Michael Milette

  4. Hello I am using Moodle 3.5 version. I have tried to user email_to_user() and it worked like a charm, when I try to use it with attachments, it dosen’t work. Mail sends but it throws error:

    related with path data folder not found:
    could not access file data/new/test.pdf email_to_user moodle

    My target folder is new but in error it adds extra folder.


    // email_to_user($userobj, ‘’, $emailsubjectcancel, $emailmessagecancel, $emailmessagecancel); // Withput attachment
    email_to_user($userobj, ‘’, $emailsubjectcancel, $emailmessagecancel, $emailmessagecancel, ‘new’, ‘test.php’); // With attachments

Leave a Reply

Your email address will not be published. Required fields are marked *