=== M SMTP ===
Contributors: majevski
Tags: smtp, email, mail, email log, wp_mail
Requires at least: 6.5
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 1.1.2
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Lightweight universal SMTP mailer: send all WordPress email through your own SMTP server, with logging, resend, reports, tracking, routing and queueing.

== Description ==

WordPress sends email with PHP's `mail()` function by default, which is unreliable and often lands in spam. **M SMTP** reconfigures `wp_mail()` to deliver every email — from WordPress core, WooCommerce, WPForms or any other plugin — through your own SMTP server.

= Features =

* **Custom SMTP** — host, port (with 25/465/587/2525 helpers), SSL/TLS/STARTTLS encryption, authentication. Credentials can also be defined as `wp-config.php` constants; stored passwords are encrypted.
* **Connection test** — verify host, encryption and login with the full SMTP conversation transcript, or send yourself a test email.
* **Email Log** — every email is recorded with subject, sender, recipients, content, headers, attachments, delivery status, error message and the plugin that sent it. Search, filter, view details, delete, automatic retention cleanup.
* **Resend & Forward** — resend any email individually or in bulk, or forward it to another address.
* **Email Reports** — sent/failed chart with open and click rates for the last 7/30/90 days.
* **Open & Click Tracking** — optional pixel and link tracking for HTML emails, with per-email engagement shown in the log.
* **Smart Conditional Routing** — route emails to different SMTP connections based on subject, message content, from/to address or source plugin. Mix transactional and marketing servers to improve deliverability.
* **Rate Limiting** — cap how many emails are sent per minute, hour, day, week or month; the rest are queued automatically.
* **Optimized Sending** — optionally queue all email and deliver it in the background via WP-Cron, keeping page loads fast.

The plugin is intentionally lightweight: no frameworks, no external services, no outbound calls other than your SMTP server.

= wp-config.php constants =

Define any of these to lock the primary connection's settings:

`MSMTP_SMTP_HOST`, `MSMTP_SMTP_PORT`, `MSMTP_SMTP_ENCRYPTION` (`none|ssl|tls`), `MSMTP_SMTP_AUTOTLS`, `MSMTP_SMTP_AUTH`, `MSMTP_SMTP_USER`, `MSMTP_SMTP_PASS`

== Installation ==

1. Upload the plugin to `/wp-content/plugins/m-smtp/` or install it from the Plugins screen.
2. Activate it.
3. Go to **M SMTP → Settings**, enter your SMTP server details and save.
4. Go to **M SMTP → Tools** and click **Test Connection**, then send yourself a test email.

== Frequently Asked Questions ==

= Queued emails are delayed. Why? =

Background sending uses WP-Cron, which only runs when your site receives visits. For reliable timing add `define( 'DISABLE_WP_CRON', true );` to `wp-config.php` and create a real cron job that requests `wp-cron.php` every minute.

= Why are some emails sent immediately even with Optimized Sending on? =

Emails carrying attachments skip Optimized Sending. Only the file paths are recorded in the log, and a plugin that writes a temporary file, sends it and deletes it straight away would leave the queue with nothing to attach — so these go out while the files are still there.

Very large messages (over 4 MB) are also sent immediately, for a different reason: a copy that big may be silently shortened by the database, and delivering a cut-off message would be worse than sending it right away.

Rate limits are a hard cap set by your mail provider, so they apply to attachment emails too. When a limit is reached, those are queued like any other email, and their files need to stay on disk until the queue delivers them. The one exception is a message too large to store intact, which is always sent immediately.

= Can every logged email be re-sent? =

Re-send and Forward rebuild the message from the stored copy, so they need "Log message body" to be enabled. With body logging off, message content is discarded once an email has been delivered: those emails still appear in the log with their subject, recipients and delivery status, but the Re-send button is not offered. Queued emails always keep their content until they are actually sent.

= Is open/click tracking GDPR friendly? =

Tracking is off by default. When enabled, opens and clicks are stored against the email log entry; IP addresses are only stored if you additionally enable that option. Mention email tracking in your privacy policy.

= Does it work with contact form plugins? =

Yes. Any plugin that sends mail through the standard `wp_mail()` function — WPForms, Contact Form 7, WooCommerce, Gravity Forms and virtually all others — is routed through your SMTP server automatically.

= My host blocks port 25. What now? =

Most providers accept encrypted submission on port 587 (STARTTLS) or 465 (SSL). Use the port preset buttons in Settings; they suggest the matching encryption.

== Changelog ==

= 1.1.2 =
* Fixed: an update that could not be downloaded now says why. WordPress gives a package download five minutes to finish, which is longer than any host allows a single admin request to run, so when the connection to majevski.com stalled the request was cut off before WordPress could report anything and the Plugins screen showed only the browser's own "Connection lost or the server is busy". Downloads of this plugin's releases are now capped at sixty seconds — far more than a release archive needs, and short enough that the real transport error is reported on the screen instead of the request dying silently.
* New: a Site Health check under Tools → Site Health → Status, "M SMTP can reach its update server". It makes the same two calls the installer makes — the release manifest, then the package itself — and prints the exact error when either fails, so a blocked outbound connection is named as such instead of appearing as a failed update.

= 1.1.1 =
* Fixed: new releases now appear on the Plugins screen within an hour instead of up to a day. WordPress only re-checks for updates every 12 hours by default and the release manifest was cached for another 12 — visiting the Plugins screen now forces a fresh check (at most hourly), and the manifest cache lasts one hour.
* New: a "Check for updates" link in this plugin's row on the Plugins screen — click it and, if a newer release exists, the native "update now" link is active immediately.

= 1.1.0 =
* New: automatic update checks against majevski.com. When a newer release is published, WordPress shows its standard update prompt with one-click install; a "View details" popup shows the changelog. The update channel is pinned to https://majevski.com over HTTPS, checks are cached and fail open, and equal or older versions are never offered.

= 1.0.0 =
* Initial release: custom SMTP delivery, connection test, email log with details and timeline, resend/forward, reports, open/click tracking, smart conditional routing, rate limiting and background queue.

== Upgrade Notice ==

= 1.1.0 =
Adds self-hosted update checks: from this version on, new releases appear in the normal WordPress update flow. Install this version manually once — older versions do not know about the update channel yet.

