WireMailTools / $mail
$mail is the API variable for sending email in ProcessWire
It provides both a
one-call send interface and a fluent builder (WireMail) for composing more complex
messages. If a WireMail module (e.g. WireMailSMTP, WireMailgun) is installed, it is
used automatically in place of ProcessWire's default WireMail (which uses PHP's
built-in mail() function.
$mail is accessible in templates as $mail, or wire()->mail and in modules as $this->wire()->mail. There is also the wireMail() function, which returns
a new WireMail instance.
$mail->send($to, $from, $subject, $body)
Send an email in a single call.
- Arguments:
send(string|array $to, string $from, string $subject, string|array $body = '', array|string $options = []) - Returns:
int— number of addresses successfully sent to (0 on failure) - If no arguments are supplied, returns a new
WireMailinstance instead. $tomay be a single address, a CSV string, or an array.$frommay be a plain address or"Name <email>"format.$bodymay be a plain-text string or an$optionsarray (skipping the text-body argument).
// Simplest form
$mail->send('user@example.com', 'you@example.com', 'Hello', 'Message body');
// Multiple recipients
$mail->send(['a@example.com', 'b@example.com'], 'you@example.com', 'Hi', 'Body');
// Named sender
$mail->send('user@example.com', 'You <you@example.com>', 'Hi', 'Body');
// With options array (HTML + text)
$mail->send('user@example.com', 'you@example.com', 'Hello', [
'body' => 'Plain text version',
'bodyHTML' => '<p>HTML version</p>',
'replyTo' => 'replies@example.com',
'headers' => ['X-Campaign' => 'newsletter-1'],
]);$mail->sendHTML($to, $from, $subject, $bodyHTML)
Like send() but the body argument is treated as HTML. A plain-text version is
auto-generated from the HTML if no body option is provided.
- Arguments:
sendHTML(string|array $to, string $from, string $subject, string $bodyHTML, array $options = []) - Returns:
int
$mail->sendHTML('user@example.com', 'you@example.com', 'Hello',
'<h1>Hello world</h1><p>This is HTML email.</p>'
);$mail->mail($to, $subject, $message)
Drop-in replacement for PHP's mail() function using the same argument order. Useful
when converting existing mail() calls to ProcessWire's mail system.
- Arguments:
mail(string|array $to, string $subject, string|array $message, array|string $headers = []) - Returns:
bool - Pass an array for
$messageto use options (bodyHTML,body,from,replyTo,headers). - The
$headersargument accepts an associative array or a"Name: Value\n"string.
// PHP mail() style
$mail->mail('user@example.com', 'Subject', 'Message body');
// With From header (PHP mail() style)
$mail->mail('user@example.com', 'Subject', 'Body', 'From: hello@example.com');
// With options array (HTML email)
$mail->mail('user@example.com', 'Subject', [
'bodyHTML' => '<h1>Hello</h1>',
'from' => 'hello@example.com',
]);$mail->mailHTML($to, $subject, $messageHTML)
Same as $mail->mail() but the message is treated as HTML with auto-generated text body.
The $headers argument is accepted in the same formats as $mail->mail().
$mail->mailHTML('user@example.com', 'Subject', '<h1>Hello</h1>');For more complex messages, get a WireMail instance and chain method calls.
$mail->new($options)
Get a new WireMail instance, optionally pre-populated with settings.
- Arguments:
new(array|string $options = []) - Returns:
WireMail - Pass
'WireMail'(string) or['module' => 'WireMail']to force PHP'smail()and skip any installed WireMail module. - Any
WireMailproperty (from,fromName,subject, etc.) may be pre-set via$options.
// Returns new WireMail instance
$m = $mail->new();
// Pre-populate with defaults
$m = $mail->new(['from' => 'no-reply@example.com', 'fromName' => 'My Site']);
// Force PHP mail() regardless of installed modules
$m = $mail->new('WireMail');Alternatively, 3.0.113 you can start a chain directly on $mail without calling
new() first — $mail proxies to(), from(), and subject() as shorthand:
// Both are equivalent:
$numSent = $mail->new()->to('user@example.com')->from('you@example.com')
->subject('Hello')->body('World')->send();
$numSent = $mail->to('user@example.com')->from('you@example.com')
->subject('Hello')->body('World')->send();All builder methods return $this (the WireMail instance) for chaining.
->to($email, $name)
Set one or more recipient addresses.
$emailmay be a single address,"Name <email>"string, CSV string, plain array, or associative[email => name]array.- Call multiple times to accumulate recipients.
- Pass
nullto clear all previously set addresses.
$m->to('user@example.com');
$m->to('John Smith <john@example.com>');
$m->to('a@example.com, b@example.com');
$m->to(['a@example.com', 'b@example.com']);
$m->to(['a@example.com' => 'Alice', 'b@example.com' => 'Bob']);
$m->to('user@example.com', 'User Name'); // name as second argument
$m->to(null); // clear all recipients->from($email, $name)
Set the sender address.
- Accepts a plain address or
"Name <email>"string. $nameas second argument is equivalent to callingfromName().
$m->from('you@example.com');
$m->from('You <you@example.com>');
$m->from('you@example.com', 'Your Name');->toName($name), ->fromName($name), ->replyToName($name)
Set display names separately from their email addresses.
toName()applies to the most recently added recipient and requiresto()first.fromName()sets the sender display name.replyToName()updates the reply-to display name and refreshes theReply-Toheader if a reply-to address is already set.
$m->to('user@example.com')->toName('User Name');
$m->from('you@example.com')->fromName('Your Name');
$m->replyTo('replies@example.com')->replyToName('Reply Team');->subject($subject)
Set the email subject.
$m->subject('Welcome to My Site');->body($body)
Set the plain-text body.
$m->body('Hello, thanks for signing up.');->bodyHTML($html)
Set the HTML body. Provide a full HTML document (not just a fragment). When bodyHTML
is set without a body, a plain-text version is auto-generated from the HTML.
$m->bodyHTML('<html><body><h1>Hello</h1><p>Thanks for signing up.</p></body></html>');->attachment($file, $filename)
Attach a file to the email.
$filemust be a full filesystem path to an existing file.$filenameoptionally overrides the name shown in the email.- Call multiple times to attach multiple files.
- Pass
nullto clear all attachments. - Support depends on the installed WireMail module.
$m->attachment('/path/to/report.pdf');
$m->attachment('/path/to/report.pdf', 'Q1-Report.pdf');
$m->attachment(null); // clear all attachments->param($value)
Add extra parameters for PHP's native mail() function, such as an envelope sender.
- Call multiple times to append multiple parameters.
- Pass
nullto clear all parameters. - These parameters only matter when ProcessWire's default
WireMailclass sends through PHPmail(); third-party WireMail modules may ignore them.
$m->param('-f bounce@example.com');
$m->param(null); // clear all params->replyTo($email, $name)
Set the reply-to address.
$m->replyTo('replies@example.com');
$m->replyTo('Replies <replies@example.com>');->header($name, $value)
Set a custom email header.
- Call multiple times to set multiple headers.
- Pass
nullas$valueto remove a header.
$m->header('X-Campaign', 'newsletter-may');
$m->header('X-Mailer', null); // remove header->headers(array $headers)
Set multiple headers at once from an associative array.
$m->headers(['X-Campaign' => 'newsletter-may', 'X-Priority' => '1']);->send()
Send the composed email. Call after all properties are set.
- Returns:
int— number of addresses successfully sent to (0 on failure) - This is a hookable method (
___send()), making it the right place for WireMail modules to override delivery behavior.
$numSent = $m->to('user@example.com')
->from('you@example.com')
->subject('Hello')
->body('Plain text')
->bodyHTML('<p>HTML version</p>')
->send();
if(!$numSent) {
// handle send failure
}Default WireMail settings are set in $config->wireMail in /site/config.php:
// Set a site-wide default from address and name
$config->wireMail('from', 'noreply@example.com');
$config->wireMail('fromName', 'My Site');
// Force a specific WireMail module
$config->wireMail('module', 'WireMailSMTP');
// Set default headers for all outgoing mail
$config->wireMail('headers', ['X-Mailer' => 'My Site']);Any WireMail property may be set as a default here (e.g. from, fromName,
subject, headers). These become the starting values for every $mail->new() call.
Prevent email from being sent to certain addresses, domains, or patterns via
$config->wireMail['blacklist'] in /site/config.php:
$config->wireMail('blacklist', [
'spam@example.com', // exact address
'@bad-host.example.com', // all addresses at this host
'@example.com', // all addresses at this domain
'example.com', // any address ending with example.com
'.example.com', // any subdomain of example.com
'/\+.*@/', // PCRE regex: block addresses with + alias
]);Test an address against the blacklist with $mail->isBlacklistEmail():
$result = $mail->isBlacklistEmail('user@example.com', ['why' => true]);
if($result === false) {
echo "Not blacklisted";
} else {
echo "Blacklisted by rule: $result"; // string describes the matching rule
}When $mail->new() is called, ProcessWire auto-detects any installed module that
extends WireMail (e.g. WireMailSMTP, WireMailgun, WireMailPHPMailer) and uses it
automatically. No code change is required — install the module and it takes over.
To force a specific module in code:
$m = $mail->new(['module' => 'WireMailGmail']);
$m = $mail->new('WireMailGmail'); // shorter aliasTo force PHP's mail() and bypass any installed module:
$m = $mail->new('WireMail');- Source files:
wire/core/WireMail/WireMail.php(builder/sender) andwire/core/WireMail/Wire(Mail Tools.php $mailAPI variable). send()returns the count of addresses emailed, not a boolean. Check$numSent > 0rather than just$numSentwhen the to-list may be empty.- When only
bodyHTMLis set (nobody), a plain-text version is automatically generated from the HTML via the hookablehtmlToText()method. - All builder methods sanitize their input — header names and values are stripped of control characters; email addresses are validated and rejected if invalid or blacklisted.
- The
X-Mailerheader is set automatically. Override it with$m->header('X-Mailer', 'My App'). param()passes additional parameters to PHP'smail()function (e.g. envelope-from-f you@example.com). This has no effect when a WireMail module handles delivery.- A list of WireMail modules can be found here: https://processwire.com/search/?q=WireMail&t=Modules
// Simple usage example
$message = $mail->new();
$message->subject('Hello world')
->to('user@domain.com')
->from('you@company.com')
->body('Hello there big world')
->bodyHTML('<h2>Hello there big world</h2>');
$numSent = $message->send();
// ProcessWire 3.0.113 lets you skip the $mail->new() call if you want:
$numSent = $mail->subject('Hello world')
->to('user@domain.com')
->from('you@company.com')
->body('Hello there big world')
->bodyHTML('<h2>Hello there big world</h2>')
->send();Click any linked item for full usage details and examples. Hookable methods are indicated with the icon. In addition to those shown below, the Wire class also inherits all the methods and properties of: Wire.
Common
Additional methods and properties
In addition to the methods and properties above, Wire
API reference based on ProcessWire core version 3.0.261