=== OneShopLab ===
Contributors: oneshoplab
Tags: woocommerce, ai, product descriptions, seo, product images
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 7.4
WC requires at least: 7.0
WC tested up to: 11.0
Stable tag: 1.9.2
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Connects your WooCommerce shop to OneShopLab and applies the product titles, descriptions, tags and images you approve there.

== Description ==

OneShopLab is a hosted service that audits product pages and writes better titles, descriptions, tags and product images with AI. **This plugin is the bridge between your WooCommerce shop and your OneShopLab account** — it requires a OneShopLab account to do anything (see *External services* below).

Nothing is ever written to your shop on its own. OneShopLab proposes; you approve, in OneShopLab; only then does the plugin write the approved change into the product.

**What the plugin does**

* Sends your published products to OneShopLab — right after you save one, and the whole catalogue whenever you ask. No public-storefront scraping.
* Applies the changes you approve in OneShopLab ("Apply to store") right away. OneShopLab notifies the plugin over a signed webhook; the plugin then fetches the approved change and writes it into the product. Images are copied into your own media library, never hot-linked.
* Refuses to overwrite a product you edited in the meantime. Before writing, it compares a hash of the current value with the one OneShopLab recorded at approval time; if they differ, the change is reported as a conflict and nothing is written.
* Never deletes your files. An image operation can take a photo off a product, but the file always stays in your media library.
* Tells you when your shop cannot apply something: a **Diagnostics** list checks that images can be saved, that your server can reach OneShopLab, that scheduled tasks run, and that PHP has enough memory — each with the fix in plain words.

**Who it is for**

Shops with a WooCommerce catalogue and a OneShopLab account, from a handful of products to several thousand. It suits merchants who want AI-written product copy and images but want to review every change before it goes live, and who would rather not copy and paste between two dashboards.

**Languages**

English, French, Spanish, German and Italian. The plugin follows your WordPress language automatically; there is nothing to configure.

**What it does not touch**

Orders, customers, carts, checkout, payments, users, coupons and settings are never read and never sent anywhere. The plugin reads product data only.

== External services ==

This plugin requires the third-party service **OneShopLab** (https://oneshoplab.com) and does not function without it. You need a OneShopLab account and a **site key** created there (site settings › Integrations). Until a site key is saved, the plugin makes no outbound request at all.

All traffic goes to `https://oneshoplab.com` over HTTPS, authenticated with your site key (`Authorization: Bearer`) and an HMAC-SHA256 request signature.

**What is sent to OneShopLab, and when**

* *Product data*, on every product save (batched and sent by a scheduled task about once a minute), on a manual "Sync everything now", and page by page during the first sync after you save your key: product id, permalink, slug, title, description HTML, tag names, category name, brand/vendor name, SKU, prices and currency, stock availability, variation ids/titles/SKUs/prices/attributes, and for each image its WordPress attachment id, its URL, its alt text and its dimensions. Image files themselves are not uploaded — only the URLs, which OneShopLab fetches.
* *Your site key*, on every request, as the credential that identifies your shop.
* *Your site URL*, in the `User-Agent` header of each request, and once as the address of the webhook endpoint when the plugin registers for instant updates.
* *Diagnostics flags*, alongside each product sync: two booleans saying whether your media folder is writable and whether WordPress scheduled tasks are running, so OneShopLab can warn you before you approve a change your shop could not apply.
* *A confirmation* after each approved change is processed, saying whether it was applied, skipped, failed or conflicted, with a short reason.

**When the plugin talks to OneShopLab**

* On product save, trash, untrash, delete and stock change (queued, then sent by the 1-minute scheduled task).
* On "Sync everything now", "Test connection", "Check for changes now" and "Test" (instant updates), when you click them.
* Every 5 minutes, to poll for approved changes — the fallback path, which also runs immediately when an inbound webhook arrives.
* On inbound webhooks: OneShopLab posts a signed notification to `/wp-json/oneshoplab/v1/webhook` on your site, which only schedules the poll above. The notification is verified with a per-site HMAC secret and is never applied directly.
* Once a day, to re-register the webhook endpoint so it heals itself.
* Every 15 minutes at most, a short `GET https://oneshoplab.com/api/health` with no credentials, used by the Diagnostics list to check that your server can make outgoing connections.

**What comes back from OneShopLab**

Only the changes you approved: for one product, a new title, a new description, a new tag list, or a set of image operations. Approved image changes carry image URLs on OneShopLab's storage, which the plugin downloads into your media library. Also: your OneShopLab site name, plan and limits, and your key's permissions and expiry, shown on the plugin's status card.

**Customer and order data never leaves your site.** The plugin does not read orders, customers, users, carts, checkout or payment data at any point, and the OneShopLab API it talks to has no endpoint for them.

Using this plugin means sending the data above to OneShopLab. Please read the service's terms and privacy policy:

* Terms of Service: https://oneshoplab.com/en/terms
* Privacy Policy: https://oneshoplab.com/en/privacy

OneShopLab processes product data with third-party AI providers to generate the proposed copy and images; the sub-processors are listed in the privacy policy above.

== Installation ==

1. Install and activate WooCommerce first — this plugin does nothing without it.
2. Install OneShopLab through Plugins › Add New, or upload the zip through Plugins › Add New › Upload Plugin, then activate it.
3. Create a site key in OneShopLab: open your site › Integrations › Create a key. The key is shown once.
4. In WordPress, open **OneShopLab** in the left menu (it is also under WooCommerce), paste the key in the **Site key** box and click Save.
5. The plugin sends your products right away. The status card turns green within a minute, and the Diagnostics list tells you if anything on your server would get in the way.

== Frequently Asked Questions ==

= Where do I get a site key? =

In OneShopLab, open your site › Integrations and create a key. It is shown once, so copy it straight into the plugin. If you lose it, create a new one and paste that instead — the old one keeps working for 24 hours after a rotation. Keys are stored encrypted in your database and never displayed again.

= Is the plugin free? =

The plugin is free and GPL-licensed. The OneShopLab service it connects to is a paid subscription with a free tier; the current plans are at https://oneshoplab.com/en/pricing. Without a OneShopLab account the plugin has nothing to connect to.

= Does it change my products without asking? =

No. Every change is proposed in OneShopLab and written to your shop only after you approve it there. The plugin also refuses to write when it detects you edited the product in the meantime, and reports that back as a conflict. Every applied change is listed on the plugin page, with the product, the field and the result.

= What happens if I deactivate the plugin? =

Everything stops: scheduled tasks are removed, and OneShopLab is asked to stop sending webhooks. Your products keep whatever changes were already applied — they are ordinary WooCommerce data. Your site key and settings are kept so reactivating just works. Deleting the plugin removes every option, transient and scheduled task it created; your products, images and WooCommerce logs are left alone.

= Which languages does it speak? =

English, French, Spanish, German and Italian. The plugin follows your WordPress site language on its own.

= Does it work on multisite? =

Yes. Each site in the network keeps its own key, settings and state.

= Which products are sent? =

Published products that are not hidden from the catalogue. Drafts, private, pending and trashed products are not sent, and a product that stops qualifying is archived in OneShopLab (reversibly). The `oneshoplab_is_product_syncable` filter lets you exclude more.

= The status says the key was revoked or expired =

Create a new key in OneShopLab and paste it into the plugin. Nothing is sent until then.

= The status says "the server clock is off" =

Requests are signed with the current time and your server's clock is more than 5 minutes out. Ask your host to enable NTP time synchronisation.

= An image could not be saved =

Open the Diagnostics list on the plugin page and press Re-check. It names the cause in plain words — most often a media folder your web server cannot write to. Technical details are in WooCommerce › Status › Logs, source "oneshoplab".

= Where are the logs? =

WooCommerce › Status › Logs, source "oneshoplab". Site keys and signatures are redacted before anything is written.

== Screenshots ==

1. The OneShopLab page: the connection card says in one line whether your shop is connected, with the last exchange, the products sent and the changes pending under it.
2. The Site key box and the Instant updates card, with the Test button that proves OneShopLab can reach your shop.
3. The Diagnostics tiles: saving images, outgoing connection, scheduled tasks and PHP memory, each with the fix in plain words when something is wrong.
4. The applied-changes log: what OneShopLab changed, on which product, and how it went.
5. A product in WooCommerce after an approved change, with the new title, description and gallery image in place.

== Changelog ==

= 1.9.2 =
* Notices from OneShopLab now appear only on the Dashboard, the Plugins page and the OneShopLab page, and can be dismissed.
* Clearer image import errors on every site language.

= 1.9.1 =
* Plugin header tidy-up for the WordPress.org directory. No change in behaviour.

= 1.9.0 =
* Internal clean-up for the WordPress.org directory: every class and constant now carries the plugin's full name as its prefix, and translations are left to WordPress. Nothing changes in your settings or your connection.

= 1.8.0 =
* OneShopLab now knows which language your shop is written in: every sync tells it your WordPress site language, so generated titles and descriptions come out in that language without you having to pick it in the site settings. Your own choice there, if you made one, still wins.

= 1.7.0 =
* Your shop now answers straight away when you press "Sync now" in OneShopLab, instead of waiting for its next scheduled check.
* The same request is used after a change that adds a photo, so the picture in OneShopLab and the one on your product page stop disagreeing for a few minutes.

= 1.6.2 =
* Changes that only rewrite the alt text of an image, take a photo off a product or reorder the gallery are applied even when your media folder cannot accept new files. They write nothing to disk, so there was never a reason to refuse them.
* Once your host fixes the permissions on your media folder, the very next change goes through. The plugin used to keep refusing for up to fifteen minutes because it remembered the old answer.

= 1.6.1 =
* The three buttons of the Connection card (Test connection, Sync everything now, Check for changes now) sit side by side again instead of one per line.
* The strip of figures under the connection status no longer leaves a large empty grey area on wide screens.
* The list of applied changes shows the product name instead of a number. A product deleted since keeps the name it had, and its number is still there as a tooltip.
* New "Clear the log" link under that list, so you can empty it yourself.

= 1.6.0 =
* The OneShopLab page was redesigned so it reads top to bottom: who you are connected to, whether it works, your site key, instant updates, diagnostics, then what was changed. The connection card now says Connected, Waiting, Key problem or Not connected in one clear line, with an icon and a colour.
* The page follows the admin colour scheme you chose in your WordPress profile, all eight of them, and stays readable in every one.
* Diagnostics are shown as four tiles, and each applied change carries a coloured Applied / Conflict / Failed / Skipped badge.
* No functional change: every button, key, sync and instant update works exactly as before.

= 1.5.0 =
* When an image cannot be added to your shop, the plugin now says why and what to do about it, in your language, instead of showing a technical English message: media folder not writable, no disk space left, expired image link, file type refused by WordPress, or image too big. The technical detail stays in the WooCommerce logs.
* New Diagnostics list on the OneShopLab page — saving images, outgoing connection, scheduled tasks and PHP memory — each with the fix in plain words when something is wrong, and a Re-check button.
* OneShopLab is told whether your shop can save images and whether your scheduled tasks run, so it can warn you before you approve a change your shop could not apply.

= 1.4.0 =
* Your photos stay yours: OneShopLab can now change one image at a time — set the main photo, add one, replace one, remove one from the product, edit an alternative text, reorder the gallery — instead of replacing the whole gallery. Removing an image only takes it off the product; the file always stays in your media library.
* If one of those images was already deleted on your side, that single change is skipped and the rest still applies. A product is never left without any image.
* OneShopLab only offers the actions this plugin can actually perform.

= 1.3.0 =
* The plugin now speaks English, French, Spanish, German and Italian, following your WordPress language on its own.

= 1.2.0 =
* Works on older shops: PHP 7.4+, WordPress 6.0+ and WooCommerce 7.0+ (was PHP 8.1 / WordPress 6.4 / WooCommerce 8.0). The site key is still stored encrypted.
* If your WordPress is older than 6.0 the plugin now says so clearly instead of doing nothing.

= 1.1.0 =
* Instant updates: OneShopLab notifies the plugin as soon as you approve a change (signed webhook); the 5-minute check stays as a fallback. New Test button on the status card.

= 1.0.0 =
* First release: catalogue push, approved-changes pull, encrypted site key, French translation.

== Upgrade Notice ==

= 1.9.0 =
Internal clean-up for the WordPress.org directory. Your connection and settings are kept.

= 1.6.1 =
Layout fixes on the OneShopLab page, product names instead of numbers in the list of applied changes, and a way to clear that list.

= 1.6.0 =
A clearer OneShopLab page: the connection state in one line, diagnostics as tiles, and the whole screen follows your admin colour scheme. Cosmetic only — nothing about how your shop syncs changes.

= 1.5.0 =
Clear, translated explanations when an image cannot be saved, plus a Diagnostics list that catches server problems before they cost you a change. Recommended for every shop.

= 1.4.0 =
Image changes are applied one operation at a time instead of replacing the whole gallery, and your files are never deleted. Update before approving image changes.

= 1.2.0 =
Lowers the requirements to PHP 7.4, WordPress 6.0 and WooCommerce 7.0. Update if your host runs an older stack.
