=== Waitlist - Back in Stock for WooCommerce ===
Contributors: motylanogha
Tags: woocommerce, back in stock, waitlist, stock notification, email
Requires at least: 6.4
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 1.0.28
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Back-in-stock waitlist for WooCommerce. Shoppers leave their email, you email them on restock. Accessible, no layout shift.

== Description ==

Plogins Waitlist adds a waitlist form to out-of-stock WooCommerce products. A shopper enters their email, and when you set the product back to "In stock", Plogins Waitlist emails everyone waiting through your site's own WordPress mailer. There is no external service, no account to sign up for, and nothing leaves your database.

The form is rendered in PHP on the single-product summary, where it sits in the normal page flow rather than being injected after load, so it does not shift surrounding content. Submitting it runs a small vanilla-JavaScript `fetch` request loaded with `defer` in the footer; the plugin adds no jQuery of its own. On variable products it hooks into WooCommerce's existing variation script so the form only appears once an unavailable variation is selected.

Accessibility was a first-class concern rather than an afterthought. The email field carries a visually hidden label, consent is a real required checkbox, and the success/error message is announced through an `aria-live` region while the form reports `aria-busy` during submission.

Subscriber data lives in a single `{prefix}_restock_waitlist` table that the plugin creates and version-tracks. A restock queues the mailing and sends it in batches on WordPress's own cron, so the request that changed the stock is not held open while the emails go out. Uninstalling drops the table, removes the plugin's options and unschedules any batch still waiting, leaving nothing behind.

Source and issues: [github.com/wppoland/plogins-waitlist](https://github.com/wppoland/plogins-waitlist) . Patches and bug reports are welcome there.

**Features**

* Waitlist form shown automatically on out-of-stock and backorder ("on backorder") product pages
* Variable products: form appears after the shopper selects an unavailable variation
* WooCommerce **My Account > Waitlists** tab for logged-in customers (review lists, leave waitlist)
* Asynchronous submit with a vanilla-JavaScript fetch call, so the page does not reload
* Email field pre-filled for logged-in customers
* Required consent checkbox for every signup
* Automatic plain-text email notification on restock, sent via `wp_mail`
* Optional heading and intro text shown above the form
* Customisable form labels, button text, on-screen submit messages, and notification email subject/intro/closing text
* Place the form with the `[restock_waitlist]` shortcode or the Elementor "Back-in-Stock Waitlist" widget
* Toggle guest (not-logged-in) subscriptions on or off
* Social-proof "N shoppers are already waiting" line above the form (optional, customisable, singular/plural aware)
* Admin subscriber list with per-product filter, CSV export, and one-click remove
* Theme-overridable form template (`yourtheme/restock/single-product/waitlist-form.php`)
* Compatible with WooCommerce HPOS (Custom Order Tables) and Cart/Checkout Blocks

= You may also like these plugins =

More free WooCommerce plugins from WPPoland:

* [Plogins Tiers](https://wordpress.org/plugins/plogins-tiers/) - quantity and volume pricing tiers with a server-rendered price table.
* [Sieve - Search & Filter](https://wordpress.org/plugins/sieve/) - fast AJAX product search and filtering for WooCommerce, with no jQuery.
* [Polski for WooCommerce](https://wordpress.org/plugins/polski/) - Polish-market compliance: GPSR, Omnibus, GDPR, invoices and storefront modules.

Browse the full catalogue at [plogins.com/](https://plogins.com/) .

Reporting a security issue: email hello@wppoland.com, and under our [coordinated disclosure policy](https://wppoland.com/en/security-policy/) we confirm within two business days, assess within five, and patch a critical issue within seven days of confirming it.

== Plogins Waitlist PRO ==

The free edition is the complete back-in-stock waitlist. **Plogins Waitlist PRO** adds demand insight and automation:

* **Demand analytics** - see what shoppers are waiting for and prioritise restocks
* **Double opt-in** - confirmed, consent-friendly signups
* **Scheduled and batched sends** - stagger notifications by batch size and interval
* **Category segmentation** - include and exclude rules per product category

Everything in the free edition stays free and open. Plogins Waitlist PRO starts at 29 EUR per year, billed in EUR.

Compare editions and pricing: [plogins.com/plogins-waitlist-pro/pricing/](https://plogins.com/plogins-waitlist-pro/pricing/)

== Installation ==

1. Install and activate WooCommerce (8.0 or later).
2. Install Plogins Waitlist from the WordPress plugin directory, or upload the `plogins-waitlist` folder to `/wp-content/plugins/`.
3. Activate the plugin through the **Plugins** screen.
4. Optionally visit **WooCommerce > Plogins Waitlist** to customise labels and notification text; sensible defaults work out of the box.
5. The waitlist form appears automatically on any out-of-stock or backorder product page.

== Frequently Asked Questions ==

= Documentation and links =

* **Documentation** - [plogins.com/plogins-waitlist/docs/](https://plogins.com/plogins-waitlist/docs/)
* **Plugin page** - [plogins.com/plogins-waitlist/](https://plogins.com/plogins-waitlist/)
* **Source code** - [github.com/wppoland/plogins-waitlist](https://github.com/wppoland/plogins-waitlist)
* **Bug reports and feature requests** - [github.com/wppoland/plogins-waitlist/issues](https://github.com/wppoland/plogins-waitlist/issues)


= Does Plogins Waitlist require WooCommerce? =
Yes. Plogins Waitlist is a WooCommerce extension and requires WooCommerce 8.0 or later. It will show an admin notice and stay inactive if WooCommerce is missing or out of date.

= How are notifications sent? =
When WooCommerce sets a product's stock status to `instock`, Plogins Waitlist queues the mailing rather than sending it inside that request. WordPress cron then walks the pending subscribers for that product (and its parent, for variations) in batches of 50, oldest signup first, emailing each one with your site's own WordPress mailer (`wp_mail`). Subscribers who are emailed successfully are marked as notified so they are not contacted twice. Filter `plogins_waitlist_notify_batch_size` to change the batch size.

= Does it work with variable products? =
Yes. Choose options in the standard WooCommerce variation form first. When the selected variation is out of stock or on backorder, the waitlist form appears and the subscription is stored for that specific variation.

= Can guests join the waitlist? =
Yes by default. You can restrict signups to logged-in customers by unchecking **Allow guest subscriptions** in **WooCommerce > Plogins Waitlist**.

= Can customers manage waitlists in My Account? =
Yes. Logged-in customers see a **Waitlists** tab under My Account with active subscriptions, current stock status, and a button to leave each list.

= Does this comply with GDPR / consent requirements? =
Every signup requires the shopper to tick an explicit consent checkbox before they can join the waitlist; the form will not submit without it. Subscriber emails are stored only in a custom table in your own WordPress database and are never sent to any external service. You are responsible for the wording of your consent label and your site's privacy policy.

= Can I export the subscriber list? =
Yes. From **WooCommerce > Plogins Waitlist > Subscribers** you can view subscribers, filter by product, and export the list as CSV.

= Does the form reload the page on submit? =
No. The form is submitted with a vanilla-JavaScript `fetch` call and the result is announced in an `aria-live` region, so the page stays put. Plogins Waitlist loads no jQuery for this; on variable products it does rely on WooCommerce's own variation script to know which variation is selected.


= Does this plugin work on WordPress Multisite? =

Yes. This plugin is compatible with WordPress Multisite. Network activate it or activate it on individual sites; each site keeps its own settings and data.

== Screenshots ==

1. The waitlist form on an out-of-stock product, where a shopper leaves their email and ticks the required consent box to be notified when it returns.
2. The Plogins Waitlist settings screen with sectioned cards and inline help for guest access, the heading and intro, form labels, on-screen messages, and notification email text.
3. A customer's My Account Waitlists tab, showing products they are waiting for, the current stock status, and a button to leave each list.

== External Services ==

Plogins Waitlist does not connect to any external services. Back-in-stock notification emails are sent through your own site's WordPress mailer (`wp_mail`); subscriber data stays in your WordPress database.

== Translations ==

Plogins Waitlist is fully translatable and ships the `plogins-waitlist.pot` template. Translations are delivered by WordPress.org language packs from translate.wordpress.org, which is where Polish, German and Spanish are being contributed; the package itself carries no compiled translation files.

== Changelog ==

= 1.0.28 =
* Fixed: the plugin logged `Warning: Class "Waitlist\Plugin" not found` on every request on any site with WP_DEBUG on. A compatibility alias kept for Plogins Waitlist PRO 1.0.2 and older was declared before the plugin's autoloader was registered, so PHP could not find the class it was aliasing. The alias now sits below the autoloader, which also means it is finally declared: for the whole time it was above, it failed and gave those old PRO versions nothing.
* Copy: the "How are notifications sent?" answer still described the email leaving the moment WooCommerce sets the stock status. It has been queued and sent in batches on WP-Cron since 1.0.25, which is what the rest of the readme says; the answer now says it too.

= 1.0.27 =
* Fixed: deactivating the plugin could throw a fatal error, and leave it impossible to switch off, on a site also running Plogins Waitlist PRO 1.0.12 or older. The deactivation routine read the name of its scheduled job off a class those PRO versions also supply, in a copy that does not carry that name. The name is now written out in full and the routine loads nothing.
* Fixed: deleting the plugin without deactivating it first left its queued mailing scheduled. `wp plugin delete` removes an active plugin without deactivating it, so uninstall now unschedules the job in the same way deactivation does.
* Added: `plogins_waitlist_should_notify`, a filter deciding whether a restock mails the people waiting for that product. Returning false skips the mailing and leaves those subscribers pending. Plogins Waitlist PRO applies its category segmentation through it instead of taking the mailing over.
* Note: if you run Plogins Waitlist PRO, update it to 1.0.14 or later at the same time. Older PRO versions remove this plugin's mailing callback on every restock and send the emails themselves, one at a time, inside the request that changed the stock. PRO 1.0.14 hands that work back to the queue here, and requires this version.

= 1.0.26 =
* Fixed: the CSV export could leave subscribers out of the file without saying so. It read the list in chunks by offset, over the same rows a queued restock mailing marks as notified while it runs, so every row that left the set took another row with it. The export now walks by a cursor on a stable key, which cannot skip or repeat. Rows come out oldest first; the list on screen is unchanged.
* Fixed: a queued batch that could not run ended the mailing for good. If the product could not be loaded on that cron tick, or the waitlist had just been switched off, the front of the list was mailed and the rest was left neither mailed nor cleared. The same batch is now retried up to three times, five minutes apart, before the mailing is abandoned.
* Fixed: queued mailings survived deactivating the plugin. They are now unscheduled with the plugin, whichever batch they were up to.
* Fixed: "Remove" on the subscriber list threw you back to page one of an unfiltered list. It now returns to the page, product filter and search you removed from.
* Fixed: a personal-data export request (Tools > Export Personal Data) hit a fatal error on the "Subscribed At" row, which tried to print a date object as a string. Static analysis had been reporting it; the analysis now runs over the shared engine directory too, which had been outside both it and the coding-standards check.
* Changed: a pending-subscriber query that names no limit of its own now reads at most 5000 rows (filter `plogins_waitlist_pending_query_limit`), and the waitlist list on a customer's account page at most 200. Neither had a ceiling before.

= 1.0.25 =
* Fixed: restocking a product no longer sends the waitlist emails inside the request that changed the stock. A product save, a REST update or an order going through used to wait for one email per waiting shopper. The mailing is now queued and sent in batches of 50 (filter `plogins_waitlist_notify_batch_size`), in the same order, to the same people.
* Fixed: the Subscribers screen read the whole table on every load. It is now paged at 50 rows (filter `plogins_waitlist_subscribers_per_page`), the summary counts come from the database so they describe the whole list, and the CSV export streams in chunks instead of loading every row first.

= 1.0.24 =
* Fixed: the PRO upgrade promo kept selling to people who had already bought the paid edition. Only the banner could be dismissed, so the sidebar promo and the locked feature cards followed a paying customer around for good. The promo now checks whether the paid edition is active and steps aside when it is.
* Fixed: arrow glyphs in the admin menu paths, and in the strings handed to translators. An arrow inside a translatable string makes the glyph every translator's problem and changes the layout in any locale that drops it.

= 1.0.23 =
* Changed: the PRO feature cards printed an arrow glyph in menu paths where the rest of the plugin and the documentation use a plain ">". Same navigation, one character that renders everywhere.

= 1.0.22 =
* Fixed: deleting the plugin left the per-user "dismiss" flag from the PRO notice in the database. Uninstall now removes it for every user, not just the one who dismissed it.

= 1.0.21 =
* Eleven strings in the privacy exporter and eraser (the data a shop hands over or deletes on a GDPR request) were tagged with the plugin's old text domain, left over from the rename away from Restock. WordPress looked them up under a name no translation file uses, so they could never appear in any language but English. They now use the plugin's own text domain.
* The placeholder in "Product #%d" had no note for translators explaining what the number is.
* "Tested up to" was declared in the plugin header as well as the readme. Only the readme is read by WordPress.org, and declaring it twice is a way to publish a compatibility claim nobody intended.

= 1.0.20 =
* The translation template was regenerated. 16 strings added to the plugin since the template was last built were missing from it, so no translator could reach them in any language, and 2 strings the plugin no longer uses have been dropped. Nothing you see changes; what a translator can see does.

= 1.0.19 =
* Fixed: the plugin reported an older version number internally than the one it was released under. That number versions the stylesheets and scripts the admin screen loads, so a browser holding the previous files kept them after an update instead of fetching the corrected ones.
* Fixed: the package no longer ships its own translation files. WordPress.org builds language packs from translate.wordpress.org, and a bundled catalogue shadows that pack, so a translation corrected upstream could not reach you until the next release. Your language now comes from the language pack, which is the copy that stays current.

= 1.0.18 =
* Declared compatibility with WooCommerce 11.0.

= 1.0.17 =
* Fixed the PRO promo on the settings screen quoting a price in PLN. PRO is priced and charged in EUR, so an admin on a Polish site was shown a zloty amount and then billed in euro, and the zloty figure was a fixed conversion that drifted from the real charge as the rate moved. The promo now shows the euro price that is actually taken.

= 1.0.16 =
* Fix: corrected the PRO pricing line. Subscriptions are priced and charged in EUR. An earlier wording claimed a different currency was offered at the payment step.

= 1.0.15 =
* Fix: turning off "Show form on product page" now only stops the automatic placement. The [restock_waitlist] shortcode and the Elementor widget keep working, and signups made through them are accepted instead of failing with "Waitlist is unavailable for this product".
* Fix: ticking "Show heading" or "Show intro text" while leaving the text field blank now shows the wording from the greyed placeholder, as the field help promises, instead of showing nothing.

= 1.0.14 =
* Fix: a variation coming back in stock now notifies the people waiting for it. WooCommerce fires a separate action for variations, and only the product-level one was listened to, so a signup made on one size or colour never triggered an email.

= 1.0.12 =
* Translations: completed Polish, German and Spanish for the PRO upgrade panel.

= 1.0.11 =
* Declared compatibility with WooCommerce 10.9.

= 1.0.10 =
* Security: prevent CSV formula injection in the subscriber export; a crafted signup email can no longer execute as a spreadsheet formula when the file is opened.

= 1.0.9 =
* Translation quality pass: corrected Polish, German and Spanish (product names kept in English, legal withdrawal terminology, WooCommerce glossary and grammar fixes).

= 1.0.8 =
* Documentation: readme links are now labelled links.

= 1.0.7 =
* Shortened display name (dropped the Plogins prefix; slug unchanged).

= 1.0.6 =
* Fixed low-contrast headings on the admin settings screen under an OS dark-mode preference.

= 1.0.5 =
* Added a Free vs PRO overview to the readme.

= 1.0.4 =
* Added bundled Polish, German and Spanish translations for the plugin interface.

= 1.0.3 =
* Internal cleanup: unified the internal code identity to Waitlist (was Restock). No change to your settings or data; legacy aliases keep older PRO builds working during the update.

= 1.0.2 =
* Added a settings-screen overview of upcoming PRO features.

= 1.0.1 =
* First stable release.

= 0.4.1 =
* Docs: added a "You may also like" section linking the other free WPPoland WooCommerce plugins. No functional changes.

= 0.4.0 =
* New: optional social-proof line above the form showing how many shoppers are already waiting for a product ("12 shoppers are already waiting for this item."). Singular/plural aware, fully customisable text with a {count} placeholder, and hidden when nobody is waiting.
* New: remove a subscriber directly from the admin Subscribers list (nonce-protected, with confirmation).

= 0.3.3 =
* New: Elementor widget for the back-in-stock waitlist form, so it can be placed with the Elementor editor. Self-guarded: loads only when Elementor is active.

= 0.3.2 =
* Fix the text domain on three admin help strings so it matches the plugin slug.

= 0.3.1 =
* Renamed to Plogins Waitlist for WooCommerce for a distinct, non-generic directory name. No functional changes.

= 0.3.0 =
* New: WooCommerce My Account **Waitlists** tab with stock status and leave-waitlist action.
* New: variation-aware waitlist signups on variable products (form shows after an out-of-stock variation is selected).
* New: settings for My Account menu label, variation prompt, and unsubscribe confirmation message.

= 0.2.0 =
* New: `[restock_waitlist]` shortcode to place the waitlist form manually (optional `id` attribute to target a specific product).
* New: optional form heading and intro text, configurable from the settings page.
* New: editable on-screen form messages (success, invalid email, missing consent, login required).
* Improved: the settings page now exposes every form label, message, and email text the engine supports, instead of relying on hardcoded defaults.
* Improved: empty optional settings now correctly fall back to the built-in defaults.

= 0.1.0 =
* Initial release.
