menu_book Navigation menu

Email API & Email Templates

info
SMTP Configuration
For instructions on configuring your SMTP provider (Gmail, SendGrid, etc.), setting up domain authentication (SPF, DKIM, DMARC), and managing global email branding via the Admin panel, please refer to the Email Setup Guide in the Front-end documentation.

To send emails programmatically from your custom controllers, forms, or extensions, Pragma CMS provides the highly robust send_email() native API.

Under the hood, this function connects to your configured SMTP server using PHPMailer. It natively handles secure authentication, HTML/Text multipart generation, and file attachments without requiring you to write complex mail headers.

Method Signature

PHP
send_email(
    string $from,            // The sender's email address 
    string $fromName,        // The sender's display name
    string|array $to,        // The recipient's email address (or array of addresses)
    string $subject,         // The email subject
    string $template,        // The template name (without extension)
    array $data = [],        // Associative array of data to inject into the template
    array $attachments = [], // Array of file attachments
    string|null $replyTo     // (Optional) The Reply-To email address
): bool

This function connects to the configured SMTP server and sends the email via PHPMailer, using the credentials and settings you have defined (SMTP host, port, username, password, security). It handles HTML formatting and automatically generates the plain-text version (which is essential for anti-spam compliance), while also supporting file attachments.

Creating Email Templates

The Email API uses a decoupled template system. To create a new email template (e.g., for a custom invoice notification or a welcome email), you must create the following files:

  1. your-template.html.php (Required): Contains the HTML markup of your email. The keys provided in your $data array are automatically extracted as local variables (e.g., passing ['username' => 'John'] allows you to output <?= $username ?> inside the template).
  2. your-template.txt.php (Optional): Contains the plain-text version of the email.
lightbulb
Automatic Plain-Text Generation
Plain-text versions are mandatory to pass modern anti-spam filters. If you do not create a .txt.php
 file, Pragma CMS will automatically parse your .html.php
 file, strip the tags, format the line breaks, and generate a clean plain-text version on the fly using the core convert_html_to_text()
 engine.

Template Override Hierarchy:

When calling a template name, the CMS looks for it in the following order:

  1. themes/[your-theme]/templates/emails/ (Allows you to override system templates easily)
  2. cms-versions/[version]/system/templates/emails/ (Core Fallback)

In summary, send_email() automatically resolves the correct HTML and text versions, extracts your $data array into local variables, and injects them into the templates before dispatching the email.

Usage Example

Here is how you would trigger an email from a custom controller or a form hook:

PHP
// 1. Prepare dynamic data for the template
$emailData = [
    'user_name' => 'John Doe',
    'invoice_number' => 'INV-2026-001'
];

// 2. Prepare attachments (must use absolute server paths)
$attachments = [
    [
        'path' => SITE_DIR . "/media/invoices/INV-2026-001.pdf",
        'name' => 'Invoice_001.pdf'
    ]
];

// 3. Dispatch the email
$success = send_email(
    '[email protected]',      // From Email
    'My Company Billing',        // From Name
    '[email protected]',      // To Email
    'Your invoice is available', // Subject
    'new-invoice',               // Template name (looks for new-invoice.html.php)
    $emailData,                  // Data injected into the template
    $attachments                 // Files to attach
);

if (!$success) {
    logError("Failed to send invoice to John Doe.");
}
warning
Important: Restrictions on the Sender Address ($from)
If you are using a standard consumer email provider (such as Gmail or Outlook) as your SMTP gateway:

The sender address you define in the $from parameter (e.g., [email protected]) will likely be ignored and overridden by the actual email address associated with your SMTP account (e.g., [email protected]).

Why does this happen?
This is a strict security measure enforced by Google and Microsoft to prevent identity theft and spoofing. They do not allow you to send emails pretending to be from an unverified domain.

The Solution for Production:
To display a professional, custom sender address (e.g., [email protected]), you must:
  1. Use a professional transactional email service (like SendGrid, Brevo, Postmark, or Mailgun).
  2. Authorize that service by configuring your domain's DNS records (SPF/DKIM/DMARC) as detailed in the Front-end documentation.

Template Example: contact-notification.html.php

Create this file in your theme folder: themes/[your-theme]/templates/emails/contact-notification.html.php.

PHP
<?php
/**
 * Variables automatically injected by the Email API
 * @var string $subject        The email subject
 * @var string $site_name      Global site name from settings
 * @var string $logo_url       Absolute URL to the site logo
 * @var string $user_name      Name of the person who filled the form
 * @var string $user_email     Email of the person who filled the form
 * @var string $message_body   The content of the message
 */
?>
<!DOCTYPE html>
<html lang="<?= $site->langCode ?? 'en' ?>">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><?= htmlspecialchars($subject) ?></title>
    <style>
        body { font-family: sans-serif; margin: 0; padding: 0; background-color: #f4f4f7; color: #51545E; }
        .container { width: 100%; max-width: 600px; margin: 0 auto; background-color: #ffffff; border: 1px solid #e2e2e2; }
        .header { padding: 25px; text-align: center; background-color: #f8f9fa; }
        .content { padding: 35px; line-height: 1.6; }
        .footer { padding: 20px; text-align: center; font-size: 12px; color: #999; background-color: #f8f9fa; }
        .data-table { width: 100%; margin-top: 20px; border-collapse: collapse; }
        .data-table td { padding: 10px; border-bottom: 1px solid #edf2f7; }
        .label { font-weight: bold; color: #333; width: 30%; }
    </style>
</head>
<body>

    <table width="100%" border="0" cellspacing="0" cellpadding="0">
        <tr>
            <td align="center" style="padding: 20px;">
                <table class="container" width="100%" border="0" cellspacing="0" cellpadding="0">
                    
                    <!-- Header -->
                    <tr>
                        <td class="header">
                            <?php if (!empty($logo_url)): ?>
                                <img src="<?= htmlspecialchars($logo_url) ?>" alt="<?= htmlspecialchars($site_name) ?>" width="140">
                            <?php else: ?>
                                <h1 style="margin: 0; font-size: 20px;"><?= htmlspecialchars($site_name) ?></h1>
                            <?php endif; ?>
                        </td>
                    </tr>

                    <!-- Body -->
                    <tr>
                        <td class="content">
                            <h2 style="margin-top: 0; color: #333;"><?= getTranslation("New Form Submission") ?></h2>
                            <p><?= getTranslation("Hello admin") ?>,</p>
                            <p><?= getTranslation("A new message has been sent from your website contact form.") ?></p>
                            
                            <table class="data-table">
                                <tr>
                                    <td class="label"><?= getTranslation("Sender") ?></td>
                                    <td><?= htmlspecialchars($user_name) ?></td>
                                </tr>
                                <tr>
                                    <td class="label"><?= getTranslation("Email") ?></td>
                                    <td><a href="mailto:<?= htmlspecialchars($user_email) ?>"><?= htmlspecialchars($user_email) ?></a></td>
                                </tr>
                            </table>

                            <div style="margin-top: 25px; padding: 20px; background-color: #f9f9f9; border-radius: 5px; border-left: 4px solid #007bff;">
                                <strong style="display: block; margin-bottom: 10px;"><?= getTranslation("Message:") ?></strong>
                                <?= nl2br(htmlspecialchars($message_body)) ?>
                            </div>
                        </td>
                    </tr>

                    <!-- Footer -->
                    <tr>
                        <td class="footer">
                            <p>&copy; <?= date('Y') ?> <?= htmlspecialchars($site_name) ?>. <?= getTranslation("All rights reserved.") ?></p>
                        </td>
                    </tr>

                </table>
            </td>
        </tr>
    </table>

</body>
</html>

Corresponding PHP Dispatch

To send this specific template from your code:

PHP
$emailData = [
    'user_name'    => 'Sarah Connor',
    'user_email'   => '[email protected]',
    'message_body' => "Hi, I'm looking for John."
];

send_email(
    '[email protected]',
    $site->settings['site_name'],
    $site->settings['admin_email'],
    'New contact from ' . $emailData['user_name'],
    'contact-notification', // Searches for contact-notification.html.php
    $emailData
);