=== WT SMTP ===
Contributors: webmastersteam
Donate link: https://webmasters.team/
Tags: smtp, email, mail-log, deliverability, debug
Requires at least: 6.7
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 1.0.7
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Lightweight SMTP for WordPress with first-class diagnostics — connect any mail provider, log delivery, troubleshoot from one panel.

== Description ==

**WT Waitlist** sends back-in-stock emails, **WT Hardening** logs security events, and now **WT SMTP** makes sure those emails actually arrive — and tells you exactly why they do not.

Built by the [webmasters.team](https://webmasters.team) team. Open-source, no external dependencies, no Pro upsell.

= Why another SMTP plugin? =

Because most SMTP plugins tell you whether a send returned `true` or `false`. WT SMTP tells you **why mail goes to spam before you even press Send**: the Settings page runs a live SPF / DKIM / DMARC / MX check against your From domain and surfaces missing records inline. No external tool, no copy-pasting domain names into third-party validators.

= Key features =

* **Drop-in SMTP** for any provider — generic host/port/encryption/auth, plus one-click presets for Gmail, Outlook / Microsoft365, SendGrid, Brevo, Mailgun, Amazon SES and MailHog (dev).
* **AES-256 password encryption at rest** when you define `WTSMTP_KEY` in `wp-config.php` — falls back to plaintext storage with a visible warning if the key is missing.
* **Mail log** in a dedicated table (`{prefix}_wtsmtp_log`) — metadata only, no bodies or attachments — with one-click resend for failed messages and configurable retention (default 30 days).
* **Live DNS health check** for the From domain — MX, SPF, DMARC, plus DKIM probing for any selectors you configure (defaults: `default`, `google`, `selector1`). Cached for 1 hour to keep the Settings page snappy.
* **Test email** with full PHPMailer `ErrorInfo` surfaced on failure — the actual reason `wp_mail()` returned `false`.
* **Conflict detection** — warns when another SMTP plugin (WP Mail SMTP, FluentSMTP, Post SMTP, Easy WP SMTP…) is also active and would fight over `phpmailer_init`.
* **Copy diagnostic info** — paste-ready text block with environment, config, log counts, DNS results and conflict notes for support tickets.
* **GDPR-friendly recipient anonymization** in the log (e.g. `j***@example.com`) — opt-in.
* **Zero external dependencies** — no Composer, no JS framework, no call-home.

== Installation ==

1. Install and activate **WT SMTP**.
2. Open **WT SMTP → Settings** in the admin.
3. (Recommended) Add `define('WTSMTP_KEY', 'a long random string');` to `wp-config.php` to enable AES-256 password encryption.
4. Pick a provider preset (or enter your own host), add credentials, set the From email, save.
5. Click **Send test email to admin** to verify the pipeline.

== Frequently Asked Questions ==

= Where do I get SMTP credentials? =

From your mail provider. Most providers (Gmail, Outlook, Brevo, SendGrid, Mailgun, Amazon SES) require an **app password** or **API-key-as-password**, not your regular account password.

= Why is the password stored in plaintext? =

It is not — if you defined `WTSMTP_KEY` in `wp-config.php`. Without it, the plugin falls back to plaintext and shows a visible warning in the Settings panel. Defining the key takes 30 seconds and is strongly recommended.

= The DNS health check shows "DNS lookups blocked by host". What now? =

Some low-cost shared hosts disable `dns_get_record()`. Use an external DNS lookup tool ([mxtoolbox.com](https://mxtoolbox.com/)) for your From domain, or move to a host that allows DNS queries. The rest of the plugin still works.

= I see "WP Mail SMTP is also active" in the System status. =

Two SMTP plugins on one site will fight over the `phpmailer_init` hook — only one wins, and you cannot predict which. Disable one.

= Will this slow down my site? =

No. SMTP wire-up only happens when `wp_mail()` is actually called. The DNS health check is cached for 1 hour. Logging is a single INSERT per send.

= Can I forward the log to my own monitoring? =

Yes. Hook the `wtsmtp/after_send` action (fires after each log INSERT) and pipe the row anywhere you like.

= Will old log entries clog the database? =

No. The plugin schedules a daily purge of entries older than the configured retention (default 30 days).

== External services ==

WT SMTP sends your site's outgoing email through an SMTP server, and it can look up your domain's email DNS records for the built-in deliverability diagnostic. Both are described below.

= Your SMTP server / provider =

When WordPress sends an email (`wp_mail()`), WT SMTP hands the message to the SMTP server you configure under Settings -> WT SMTP. The email (its headers, subject, recipients and body) and the SMTP username and password you entered are transmitted to that server whenever WordPress sends a message.

The SMTP server can be your own mail server or a third-party provider. For convenience the plugin ships connection presets for the providers below; choosing a preset only fills in the host and port. You still enter your own credentials, and nothing is sent anywhere until WordPress actually sends an email:

* Gmail / Google Workspace - terms: https://policies.google.com/terms - privacy: https://policies.google.com/privacy
* Microsoft 365 / Outlook - terms: https://www.microsoft.com/servicesagreement - privacy: https://privacy.microsoft.com/privacystatement
* SendGrid (Twilio) - terms: https://www.twilio.com/legal/tos - privacy: https://www.twilio.com/legal/privacy
* Brevo (Sendinblue) - terms: https://www.brevo.com/legal/termsofuse/ - privacy: https://www.brevo.com/legal/privacypolicy/
* Mailgun - terms: https://www.mailgun.com/legal/terms/ - privacy: https://www.mailgun.com/legal/privacy-policy/
* Amazon SES - terms: https://aws.amazon.com/service-terms/ - privacy: https://aws.amazon.com/privacy/

If you use a different SMTP server, its own terms and privacy policy apply. WT SMTP does not send your data to webmasters.team or any of its own servers.

= Domain DNS lookup (deliverability diagnostic) =

The optional "DNS health check" on the settings screen performs standard public DNS lookups (MX, SPF, DMARC and DKIM records) for your site's own email domain, using PHP's `dns_get_record()`. It is a normal DNS query and the result is cached for one hour. No personal data is sent, and the lookup only runs when you open the diagnostic.

== Screenshots ==

1. Settings page — SMTP connection, provider presets, From override.
2. System status panel with live DNS health check (SPF, DKIM, DMARC, MX).
3. Mail Log — every outgoing email with sent / failed status and resend.

== Changelog ==

= 1.0.7 =
* Fix: raised the minimum PHP version to 8.1 to match the code (the plugin uses readonly properties, introduced in PHP 8.1); this prevents a parse error when activated on PHP 8.0.

= 1.0.6 =
* Housekeeping: renamed internal code identifiers (defines, options, hooks, transients, admin-page slugs) to the unique `wtsmtp` prefix to avoid conflicts. The public action hook is now `wtsmtp/after_send`; the encryption constant is now `WTSMTP_KEY`.

= 1.0.5 =
* Docs: documented the external services the plugin uses (the configured SMTP server/provider and the domain DNS deliverability lookup).
* New: the documented `wtsmtp/after_send` action now fires after each mail-log entry is written.
* Housekeeping: moved "Tested up to" out of the main plugin file (readme is the single source), removed the plugin header URI.

= 1.0.4 =
* Compatibility: tested up to WordPress 7.1.

= 1.0.3 =
* Raised the minimum required WordPress version to 6.7 and use `wp_get_wp_version()` (the recommended replacement for the global `$wp_version`) for the WordPress version shown in the System Status diagnostics. No user-facing change.

= 1.0.2 =
* Compatibility: use `wp_get_wp_version()` (WordPress 6.7+) instead of reading the global `$wp_version` in the System Status diagnostics, with a fallback for older cores. No user-facing behaviour change.

= 1.0.1 =
* Pre-approval hardening: addressed Plugin Check findings on the initial submission. No user-facing behaviour change.
  * Explicit `wp_unslash()` + `absint()` on all `$_GET` reads in the Mail Log list table.
  * Documented `phpcs:ignore` annotations on nonce checks that happen later in the same flow (Mail Log resend, list-table filters).
  * Class-level `phpcs:disable` with rationale on the mail-log repository — every query targets the plugin's own `{prefix}_wtsmtp_log` table built from `$wpdb->prefix`, no user-controlled identifiers anywhere.
  * Same annotation on the `uninstall.php` DROP TABLE.

= 1.0.0 =
First public release.

* SMTP configuration with one-click provider presets (Gmail, Outlook / Microsoft365, SendGrid, Brevo, Mailgun, Amazon SES, MailHog).
* AES-256 password encryption at rest using `WTSMTP_KEY` (fallback to `AUTH_KEY` or plaintext with a warning).
* Custom mail-log table (`{prefix}_wtsmtp_log`) — metadata only, no bodies or attachments.
* Mail log admin screen with filtering, search, bulk delete and one-click resend.
* Test email AJAX with PHPMailer `ErrorInfo` surfaced on failure.
* Live DNS health check (MX / SPF / DMARC / DKIM with configurable selectors).
* Conflict detection for other SMTP plugins (WP Mail SMTP, FluentSMTP, Post SMTP, Easy WP SMTP, WP SMTP, WP Mail Bank).
* Copy-to-clipboard support diagnostic snippet.
* Opt-in GDPR recipient anonymization in the log.
* Daily purge cron with configurable retention (default 30 days).

== Upgrade Notice ==

= 1.0.7 =
Requires PHP 8.1 or newer.

= 1.0.6 =
Internal identifiers renamed to a unique prefix (wtsmtp). If you defined WT_SMTP_KEY or hooked wt_smtp/after_send, use WTSMTP_KEY and wtsmtp/after_send instead.

= 1.0.4 =
Confirmed compatible with WordPress 7.1. No code changes.

= 1.0.3 =
Minimum WordPress version is now 6.7. System Status diagnostics use wp_get_wp_version(). No data changes.

= 1.0.2 =
Minor compatibility update for the System Status panel. No behaviour or data changes - safe upgrade.

= 1.0.1 =
Pre-approval Plugin Check hardening. No behavioural change — safe upgrade.

= 1.0.0 =
First public release.
