=== WT Waitlist ===
Contributors: webmastersteam
Donate link: https://webmasters.team/
Tags: woocommerce, waitlist, back-in-stock, stock-notifier, notifications
Requires at least: 6.0
Tested up to: 7.0
Requires PHP: 8.0
Stable tag: 1.0.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Lightweight waitlist for WooCommerce — automatic email notifications when an out-of-stock product (or variation) is back in stock.

== Description ==

**WT Waitlist** is a "back in stock" waitlist for WooCommerce without bloat. Customers leave their email on an out-of-stock product page, and when the stock returns — the plugin sends a notification in the background through Action Scheduler.

Built by the [webmasters.team](https://webmasters.team) team. Open-source code, no external APIs, all data stored locally in the WordPress database.

= Key features =

* **Signup form replaces Add to cart** for out-of-stock products, with variation support (per size/color).
* **Custom database tables** (`{prefix}_waitlist_subscriptions`) — we do not clutter `wp_postmeta`, the plugin scales to tens of thousands of subscriptions.
* **Action Scheduler queue** (bundled with WooCommerce): batch of 50 emails per tick, automatic retries, retry log visible in `WooCommerce → Status → Scheduled Actions`.
* **5 min throttle** per product — prevents duplicate sends when multiple hooks fire (e.g. quantity change followed by status change).
* **One-click unsubscribe** via a link in the email (SHA-256 token), no confirmation or login required.
* **GDPR-ready**: consent logging (anonymized IP, timestamp, user agent), integration with WordPress Privacy Tools (export and erasure of data per email).
* **CSV export** of subscribers from the admin panel (streamed, no timeouts on large lists).
* **Anti-spam**: honeypot plus rate limiter per IP (10 submissions per hour).
* **Theme compatibility**: classic themes (Storefront, Twenty Twenty-One/Two/Three) plus block themes (Twenty Twenty-Four/Five) — the form attaches through a hook for classic templates and through a `render_block` filter for FSE.
* **Zero external dependencies**: apart from WooCommerce, requires only plain PHP 8.0+.

= Shortcode fallback =

`[wt_waitlist product_id="123"]` — use this if your custom product template does not fire the standard hooks.

= What WT Waitlist does NOT do (by design) =

* No SMS, no Mailchimp/MailerLite integrations in the free version.
* No double opt-in (minimal flow — leave email, get notification).
* No WYSIWYG editor for email templates (HTML template lives in the plugin file, override with the `wt_waitlist/notification_context` filter).

These features are planned for the Pro edition. The free edition covers 100% of the core waitlist flow.

== Installation ==

1. Install and activate WooCommerce (required).
2. Install **WT Waitlist** via WP Admin → Plugins → Add new, or manually over FTP (folder `wt-waitlist` in `wp-content/plugins/`).
3. Activate the plugin.
4. Open the **WT Waitlist** menu in the admin panel and configure data retention plus the administrator notification email address.

On first activation the plugin creates its database tables and schedules a daily job that purges old subscriptions.

== Frequently Asked Questions ==

= How does the form appear on the product page? =

Automatically — the plugin hooks into the standard WooCommerce action (`woocommerce_single_product_summary`) for classic themes and into the `render_block` filter for block themes (FSE). The form is shown only when the product is out of stock.

= What if my theme or template does not fire WooCommerce hooks? =

Use the shortcode `[wt_waitlist product_id="123"]` — it works everywhere, from page builders to custom single product templates.

= How many emails are sent at once? =

Action Scheduler processes batches of 50 subscribers per tick. For a product with 1000 subscribers we queue 20 batches, each processed asynchronously, without blocking the PHP request.

= Do emails go through my WP Mail configuration? =

Yes. We use `wp_mail()` — if you have WP Mail SMTP, SendGrid, Amazon SES etc. configured, the mail travels through them. The plugin does not hardcode any provider.

= What happens to the data after uninstalling the plugin? =

The `uninstall.php` file drops the tables and deletes the options. Clean. If you deactivate without deleting, the data stays — you can reactivate without losing subscriptions.

= GDPR compliance? =

The plugin stores anonymized IPs (last octet zeroed), consent timestamp and user agent. It integrates with WordPress Privacy Tools — a customer can request data export or deletion through the standard WordPress flow.

= The signup form does not appear on my product page. What now? =

First check whether the product is actually out of stock — the form replaces the **Add to cart** button only when stock is zero (or the variation is unavailable). If the product is out of stock and the form still does not appear, your theme likely uses a custom single-product template that bypasses the standard WooCommerce hooks. Drop the shortcode `[wt_waitlist product_id="123"]` directly into the product description or template. The shortcode also works inside page builders (Elementor, Bricks, Divi).

= Customers submit the form but no notification email arrives. =

Open **WT Waitlist → Settings** and click **Send test email to admin**. If the test email arrives — `wp_mail()` works and notifications will be delivered as soon as the product returns to stock (give Action Scheduler 1–2 minutes to process the batch). If the test email does **not** arrive, the problem is on your mail pipeline, not on the plugin. Install the free **WP Mail SMTP** plugin and route mail through a transactional provider (SMTP2GO, Brevo, SendGrid, Amazon SES). Shared hosting often blocks `mail()` silently.

= How do I check whether stock notifications are queued? =

Open **WooCommerce → Status → Scheduled Actions** and filter by hook `wt_waitlist_*`. You will see pending and completed jobs with timestamps. If nothing appears after a stock change, check the **System status** panel inside **WT Waitlist → Settings** — it shows whether Action Scheduler is available and how many `wt_waitlist_*` jobs are pending.

= Something is broken and I want to send a support ticket. =

Open **WT Waitlist → Settings**, click **Copy diagnostic info** and paste the resulting block into your email to support. It includes plugin/WP/WC/PHP versions, theme info, table state, subscription counts, recent email log, Action Scheduler status and a sample of out-of-stock products with their purchasable / backorders state — everything we need to diagnose the issue without going back and forth.

= I use Flatsome / Avada / Enfold / Porto and the form does not appear. =

Themes with custom product-page templates (Flatsome UX Builder, Avada Builder, Enfold templates, Porto) often replace the standard WooCommerce single-product template, which bypasses the hooks WT Waitlist uses to attach the signup form. As of **v1.0.3** we ship multiple compatibility layers, including a `wp_footer` JS DOM-injection fallback that should handle most of these themes automatically. The plugin also detects these themes and shows a compatibility note inside **WT Waitlist → Settings → System status**.

If the form still does not show:

* In Flatsome, switch the product template to **Default** in *Flatsome → Theme Options → WooCommerce → Product Page*.
* Or place the shortcode `[wt_waitlist product_id="123"]` directly inside the product description / UX block / Custom HTML block.

= My product is marked out of stock but customers can still add it to the cart, and the waitlist form does not appear. =

That means the product has **backorders enabled** (Product → Inventory → Allow backorders). WooCommerce treats it as purchasable even though `is_in_stock()` returns false — and your customers see the standard "Add to cart" button alongside a backorder notice. WT Waitlist still renders its signup form for such products (so both signup paths coexist), but if the form is missing on a backorder-allowed product, check the **Sample out-of-stock products** section inside the diagnostic info (button **Copy diagnostic info**) — it lists `is_purchasable / backorders_allowed / subscribers` per OOS product so you can see exactly how WooCommerce treats each item.

== Screenshots ==

1. Waitlist form on a WooCommerce out-of-stock product page.
2. Subscriber management screen in the admin with filters, statuses and CSV export.
3. Notification email delivered when the product is back in stock.

== Changelog ==

= 1.0.4 =
* **Fix: signup form rendered twice** on most themes. Two of the rendering layers shared one callback that did not check the "already rendered" guard, so the form appeared duplicated. Resolved — the form now renders exactly once.
* **Fix: signup form not appearing on variable products** when a selected variation is out of stock or on backorder. The variation-aware JavaScript relied on `is_in_stock`, which is `true` for `onbackorder` variations. The plugin now tags each variation server-side (`woocommerce_available_variation`) with an explicit waitlist flag, so the form shows correctly for every non-`instock` variation.
* New: **Editable signup form text** — the form heading, description, button label and success message can now be customized under WT Waitlist → Settings → "Signup form text". Leave a field empty to keep the built-in translated default.
* i18n: translated the last two hardcoded Polish fallback strings in the frontend script (connection / generic error messages).

= 1.0.3 =
* **Fix: signup form was not appearing on backorder-allowed products.** WooCommerce has three stock statuses — `instock`, `outofstock` and `onbackorder` — and `WC_Product::is_in_stock()` returns `true` for both `instock` and `onbackorder`. The previous version's check `!is_in_stock()` therefore skipped backorder products entirely. We now use `get_stock_status() !== 'instock'` so the form is rendered (and accepts signups) for both true-OOS and backorder products. This is the primary fix in 1.0.3 — strongly recommended for any store using WooCommerce backorders.
* New: **Two additional rendering layers for theme compatibility** — `woocommerce_after_single_product_summary` (Layer 4) and `wp_footer` + JS DOM injection (Layer 5). Fixes "signup form does not appear" on themes that bypass the standard WooCommerce summary hooks (Flatsome UX Builder, Avada Builder, Enfold, Porto and similar page-builder driven themes).
* New: **Sample out-of-stock products** section in System status — for the first 5 OOS products shows `is_in_stock / is_purchasable / backorders_allowed / subscribers` so backorder vs. waitlist conflicts are immediately visible.
* New: **Theme compatibility hints** — System status now reports the active theme template slug and surfaces a known-incompatibility note for Flatsome / Avada / Enfold / Porto.
* i18n: **All user-facing strings translated to English** (admin Settings labels, signup form, error messages, email templates, unsubscribe page, admin list table). Polish-only release is over — the plugin now ships in English by default.
* Docs: new FAQ entries covering Flatsome/builder-theme rendering and backorder-vs-waitlist behavior.

= 1.0.2 =
* New: **System status** panel inside WT Waitlist → Settings — versions, DB tables, subscription counts, Action Scheduler state and recent email log at a glance.
* New: **Send test email to admin** button — one-click verification that `wp_mail()` works on this site (surfaces PHPMailer error string on failure).
* New: **Copy diagnostic info** button — generates a paste-ready support snippet so you do not have to copy values by hand.
* New: **Quick start** panel at the top of the settings page explaining the out-of-stock → form → Action Scheduler → email flow in four lines.
* Tweak: fixed `WT_WAITLIST_VERSION` constant that still reported `0.1.0` in cached environments.

= 1.0.1 =
* Fix: replaced inline `<style>` block in the unsubscribe page with `wp_register_style()` + `wp_print_styles()` (WP guideline compliance).

= 1.0.0 =
First public release.

* Waitlist form on product pages (simple + variable), classic and block theme support.
* Custom database tables (`{prefix}_waitlist_subscriptions`, `{prefix}_waitlist_email_log`).
* Stock-status change detection through WooCommerce hooks.
* Notification queue through Action Scheduler with 5 min throttle and batches of 50.
* One-click unsubscribe with SHA-256 token.
* Admin panel: subscriber list with filters and CSV export.
* Product-edit widget showing waitlist count.
* Integration with WordPress Privacy Tools (export + eraser).
* Shortcode `[wt_waitlist]` as fallback.
* Honeypot plus rate limiter (10/hour per IP).
* Automatic purge of old subscriptions (configurable retention).

== Upgrade Notice ==

= 1.0.4 =
Fixes the form rendering twice and the form not appearing on out-of-stock variable products. Adds editable form text. Recommended for all users on 1.0.3.

= 1.0.3 =
Critical fix — signup form is now rendered for products on backorder (previously skipped), plus extra rendering layers for Flatsome / Avada / Enfold / Porto themes, sample-OOS-products diagnostics and full English UI. Strongly recommended upgrade.

= 1.0.2 =
Adds a System Status panel and a Send-test-email button to Settings — much easier to troubleshoot "form does not appear" or "emails not arriving" without leaving WP Admin.

= 1.0.1 =
Compliance fix for the unsubscribe page styling. No behavior changes.

= 1.0.0 =
First public release. Requires WooCommerce ≥ 7.0 and PHP 8.0+.
