To override WordPress’s default email functionality and use Symfony Mailer with your own SMTP settings for features like password resets, contact forms, and comments, and even intergration with other smtp servers or even set wordpress to easily work with mailhog or mailtrap for email testing follow these steps:
Step 1: Install Symfony Mailer
composer require symfony/mailer
Step2: Create a Mail Service Provider
In sage you can do this fast and easy using the wp acorn command: wp acorn make:provider MailServiceProvider
If you not using acorn in the app/Providers
directory of your sage theme project, create a new file named MailServiceProvider.php
. This will handle the configuration and integration of Symfony Mailer.
namespace App\Providers;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mailer\Transport;
use Symfony\Component\Mime\Email;
use Illuminate\Support\ServiceProvider;
class MailServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton('mailer', function () {
$dsn = sprintf('%s://%s:%s@%s:%s',
env('SMTP_TRANSPORT', 'smtp'),
env('SMTP_USER', ''),
env('SMTP_PASS', ''),
env('SMTP_HOST', ''),
env('SMTP_PORT', '')
);
$transport = Transport::fromDsn($dsn);
return new Mailer($transport);
});
}
public function boot(): void
{
add_action('admin_menu', [$this, 'add_smtp_settings_page']);
add_action('admin_init', [$this, 'register_smtp_settings']);
add_action('admin_post_send_test_email', [$this, 'send_test_email']);
add_filter('wp_mail', function ($args) {
$mailer = resolve('mailer');
try {
$message = (new Email())
->from($args['from'])
->to($args['to'])
->subject($args['subject'])
->html($args['message']);
$mailer->send($message);
return $args;
} catch (\Exception $e) {
error_log("Mailer error: " . $e->getMessage());
return false;
}
});
add_filter('phpmailer_init', function ($phpmailer) {
$phpmailer->isSMTP();
$phpmailer->Host = env('SMTP_HOST');
$phpmailer->SMTPAuth = true;
$phpmailer->Username = env('SMTP_USER');
$phpmailer->Password = env('SMTP_PASS');
$phpmailer->SMTPSecure = env('SMTP_ENCRYPTION', 'tls');
$phpmailer->Port = env('SMTP_PORT');
});
}
public function add_smtp_settings_page()
{
add_options_page('SMTP Settings', 'SMTP Settings', 'manage_options', 'smtp-settings', [$this, 'render_smtp_settings_page']);
}
public function render_smtp_settings_page()
{
?>
<div class="wrap">
<h1>SMTP Settings</h1>
<form method="post" action="options.php">
<?php
settings_fields('smtp_settings_group');
do_settings_sections('smtp-settings');
?>
<table class="form-table">
<tr valign="top">
<th scope="row"><label for="smtp_host">SMTP Host</label></th>
<td><input type="text" name="smtp_host" value="<?php echo esc_attr(get_option('smtp_host')); ?>" /></td>
</tr>
<tr valign="top">
<th scope="row"><label for="smtp_user">SMTP Username</label></th>
<td><input type="text" name="smtp_user" value="<?php echo esc_attr(get_option('smtp_user')); ?>" /></td>
</tr>
<tr valign="top">
<th scope="row"><label for="smtp_pass">SMTP Password</label></th>
<td><input type="password" name="smtp_pass" value="<?php echo esc_attr(get_option('smtp_pass')); ?>" /></td>
</tr>
<tr valign="top">
<th scope="row"><label for="smtp_port">SMTP Port</label></th>
<td><input type="text" name="smtp_port" value="<?php echo esc_attr(get_option('smtp_port')); ?>" /></td>
</tr>
<tr valign="top">
<th scope="row"><label for="smtp_encryption">SMTP Encryption</label></th>
<td>
<select name="smtp_encryption">
<option value="tls" <?php selected(get_option('smtp_encryption'), 'tls'); ?>>TLS</option>
<option value="ssl" <?php selected(get_option('smtp_encryption'), 'ssl'); ?>>SSL</option>
<option value="none" <?php selected(get_option('smtp_encryption'), 'none'); ?>>None</option>
</select>
</td>
</tr>
</table>
<?php submit_button(); ?>
</form>
</div>
<?php
}
public function register_smtp_settings()
{
register_setting('smtp_settings_group', 'smtp_host');
register_setting('smtp_settings_group', 'smtp_user');
register_setting('smtp_settings_group', 'smtp_pass');
register_setting('smtp_settings_group', 'smtp_port');
register_setting('smtp_settings_group', 'smtp_encryption');
}
public function send_test_email()
{
$to = sanitize_email($_POST['test_email']);
$mailer = resolve('mailer');
try {
$message = (new Email())
->from(env('SMTP_FROM_EMAIL'))
->to($to)
->subject('Test Email')
->html('<p>This is a test email from your WordPress SMTP configuration.</p>');
$mailer->send($message);
wp_redirect(add_query_arg('status', 'success', wp_get_referer()));
} catch (\Exception $e) {
wp_redirect(add_query_arg('status', 'failure', wp_get_referer()));
}
exit;
}
}
Step 3: Register the Service Provider
In sage you can do this either in the functions.php
, ThemeServiceProvider
or in the config/app.php
for as I will in this example:
'providers' => [
// Other service providers...
App\Providers\MailServiceProvider::class,
],
Step 4: Configure Your SMTP Settings
Now, you need to configure the SMTP settings in your .env
file. Add the following variables to specify the SMTP settings:
SMTP_TRANSPORT=smtp
SMTP_HOST=smtp.yourmailserver.com
SMTP_PORT=587
SMTP_USER=your_smtp_username
SMTP_PASS=your_smtp_password
SMTP_ENCRYPTION=tls
SMTP_FROM_EMAIL=your_email@example.com
SMTP_FROM_NAME=Your Site Name
Now you can test if everything is working by mimicking a forgot password scenario.
All the best and hopefully you find this intresting, give this post a like to let me know atleast you found this helpful you can as well ask questions if this was cumbersome.