Where Smarty actually fits in the mail path
Smarty is a presentation layer. It compiles .tpl files into PHP and returns rendered HTML strings, and that is the full extent of its involvement with your messages. When a Smarty-based application sends an order confirmation or a password reset, Smarty only produces the body text; the actual transmission is handled by whatever mail library the application wraps around it. That distinction matters because delivery problems are almost never fixable inside a template. They live in the transport configuration, the sender headers, or the DNS records that receiving servers inspect before they accept a message.
On a typical Smarty application, the rendered body is passed to one of three things: PHP's built-in mail() function, a bundled library such as PHPMailer or Symfony Mailer, or a framework mail component. The default and most fragile path is mail(), which hands the message to the local sendmail binary with no authentication. On a shared LiteSpeed and CloudLinux stack that path works for mail addressed to accounts on the same server, but messages to Gmail, Outlook, and corporate filters are frequently thrown into spam or rejected outright. They arrive with an envelope sender the receiving server cannot verify, no DKIM signature tied to a deliberate configuration, and sometimes a mismatched From domain. The fix is to stop relying on the raw local handoff and route everything through authenticated SMTP using a real mailbox you create in your control panel.
Before changing anything, confirm what the application is doing. In cPanel open File Manager and look at the application's mail configuration file, which is usually under the document root in a config/ or includes/ directory. Search for strings like mail(, SMTPAuth, Host, or Mailer. Then open the account's error_log (it appears in the same directory as the script that ran) and reproduce a send. PHP warnings such as mail(): Failed to connect to mailserver or PHPMailer SMTP connect() failed lines tell you exactly which transport is active and why it is failing. This evidence decides every later step.
Creating a mailbox and wiring authenticated SMTP
The foundation of reliable delivery is a dedicated mailbox that lives on your domain. In cPanel go to Email Accounts, click Create, and make something like no-reply@yourdomain.com with a strong password. In DirectAdmin the equivalent is E-Mail Manager → E-Mail Accounts → Create Account. After the mailbox exists, open its Connect Devices (cPanel) or mail settings (DirectAdmin) page to read the exact SMTP values. Use the domain's own mail hostname, for example mail.yourdomain.com, with port 465 for implicit TLS (SSL) or port 587 for STARTTLS. Authenticate with the full email address as the username and the mailbox password. Because the application and the mail server sit on the same account, you can also use localhost as the host, but naming the real hostname keeps TLS certificate validation clean.
Now point the application at those values. If your Smarty app bundles PHPMailer, the configuration block looks like this:
$mail = new PHPMailer\PHPMailer\PHPMailer(true);
$mail->isSMTP();
$mail->Host = 'mail.yourdomain.com';
$mail->SMTPAuth = true;
$mail->Username = 'no-reply@yourdomain.com';
$mail->Password = 'your-mailbox-password';
$mail->SMTPSecure = PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_SMTPS;
$mail->Port = 465;
$mail->setFrom('no-reply@yourdomain.com', 'Your Site');
$mail->addReplyTo('support@yourdomain.com', 'Support');If the application instead uses a Symfony Mailer DSN stored in a config or .env style file, the equivalent string is smtp://no-reply%40yourdomain.com:password@mail.yourdomain.com:465. Note the URL-encoded @ in the username as %40, which is a common cause of silent authentication failures. Whatever library is in use, the principle is identical: supply host, port, encryption, and credentials for the mailbox you just created.
Applications that only call mail() and expose no SMTP settings are harder, because there is no supported way to inject SMTP without editing code. Two unprivileged options exist. First, if you can edit the sending function, replace the mail() call with a small PHPMailer send using the block above; drop the PHPMailer source into a libs/ folder through File Manager and require it. Second, if the code cannot be touched, at least force a correct envelope sender so the local handoff is accepted. Create or edit a .user.ini file in the document root and add:
sendmail_path = "/usr/sbin/sendmail -t -i -f no-reply@yourdomain.com"The -f flag sets a Return-Path on your own domain, which greatly improves acceptance even without full SMTP. Changes to .user.ini are picked up after the PHP worker recycles, typically within a few minutes on the LiteSpeed stack.
Sender headers and DNS alignment that keep mail out of spam
Authenticated SMTP solves the transport, but inbox placement depends on three DNS records that receiving servers check. All of them are editable from your own control panel under Zone Editor in cPanel or DNS Management in DirectAdmin, and none require root. The first is SPF. Your account already ships with a record, and you simply need to confirm it authorizes the server to send for your domain. A standard value is v=spf1 +a +mx +ip4:YOUR.SERVER.IP ~all, though on managed hosting an include: for the provider is common. Never publish two SPF records on the same name; merge them into one, because multiple SPF records invalidate the check.
The second record is DKIM. In cPanel open Email Deliverability, which validates SPF, DKIM, and PTR in one screen and offers a Manage button that auto-generates any missing record for the domain. DirectAdmin exposes the same under E-Mail Manager → DKIM. Enabling DKIM signs outgoing messages from your mailbox cryptographically, and because you are now sending through that authenticated mailbox, the signature matches. The third record is DMARC, a TXT entry on _dmarc.yourdomain.com such as v=DMARC1; p=none; rua=mailto:postmaster@yourdomain.com. Start with p=none so you can monitor reports without risking legitimate mail, then tighten later.
On the application side, make sure the visible From address uses the same domain as your SPF and DKIM. A mismatch, such as sending as noreply@gmail.com while authenticating as your own domain, breaks DMARC alignment and routes mail to spam. Use your domain for From and point Reply-To at a monitored address. This same alignment discipline applies to any PHP application that sends transactional mail, and the troubleshooting pattern mirrors what we documented for AzuraCast SMTP delivery on shared hosting.
Queue handling, throttling, and verification
Shared accounts enforce an hourly outbound mail limit to protect server reputation, so an application that blasts a newsletter synchronously will hit the cap and silently drop the overflow. Keep heavy sending out of the request cycle. If your Smarty application stores pending messages in a database table and flushes them, drive that flush with a Cron Job from the control panel rather than during a page load. A conservative schedule such as */5 * * * * /usr/local/bin/php /home/user/public_html/cron/send_queue.php processes a small batch every five minutes and stays under the limit. Have the queue script send a capped number per run and log each result to a file you can read in File Manager.
Verify the whole chain methodically. Trigger a single test message to an external Gmail account, then open the received message and use Show original to read the authentication results. You want to see spf=pass, dkim=pass, and dmarc=pass. If DKIM fails but SPF passes, the message probably left through the local mail() path instead of your authenticated mailbox, so recheck that the SMTP block is actually being executed. If SPF fails, the sending IP is not in your record. Watch the mailbox's own outbound activity under Track Delivery in cPanel, which shows the sender, recipient, and the remote server's accept or reject response. A 550 or greylisting message there tells you the problem is now on the receiving side rather than your configuration. Working methodically through transport, senders, DNS, and queue limits turns intermittent, invisible failures into a predictable, debuggable mail path.