=== Skryx Search for WooCommerce ===
Contributors: skryx
Tags: search, woocommerce, autocomplete, ai, multilingual
Requires at least: 6.9
Tested up to: 7.0
Requires PHP: 8.0
Stable tag: 1.3.2
WC requires at least: 8.0
WC tested up to: 10.8
License: GPLv2 or later

AI-powered product search with instant autocomplete, semantic understanding across 30+ languages, and native morphology (diacritic-aware) for major European languages. One-click install — paste keys, sync, done.

== Description ==

Skryx Search replaces WordPress's default product search (which doesn't understand diacritics, plurals, synonyms or typos) with a real, AI-powered search engine purpose-built for European e-commerce.

**Features**

* **Instant autocomplete dropdown** — search results appear as the shopper types, no full-page reload
* **30+ languages** — AI semantic search understands shopper intent across 30+ languages in a single query box
* **Native morphology** — diacritic-, plural- and declension-aware for Romanian, English, German, French, Italian, Spanish and Polish (e.g. "bormasina" finds "Bormașină", "roti" finds "Roată")
* **AI-powered ranking** — Auto-Pilot analyses your catalogue and tunes ranking, synonyms, and typo tolerance automatically
* **Real-time sync** — product saves / stock changes / deletes propagate to Skryx within seconds
* **Variable products** — variation attributes (size / colour) are searchable as part of the parent product
* **Storefront-ready** — auto-attaches to the search box on Storefront and other common themes; manual CSS selector + `[skryx_search]` shortcode for custom themes

**Tenant flow**

1. Install the plugin
2. Get your Skryx API keys at https://skryx.io/dashboard → API Keys
3. Paste secret key (sk_live_…) + public key (pk_live_…) into the plugin settings
4. Click "Connect & Sync All Products"
5. Done — search now works with AI, diacritics, and an instant dropdown

== External services ==

This plugin connects to the Skryx search service (https://skryx.io) — the
AI search engine that powers the plugin. Skryx is required for the plugin
to function; you provide your own Skryx API keys during setup.

What data is sent, and when:

* **Your product catalogue** (title, description, price, stock status, image
  URLs, categories, brands, SKU, variation attributes) is sent to the Skryx
  API (`https://api.skryx.io`) when you run a sync and whenever a product is
  created, updated or deleted, so it can be indexed for search.
* **Shopper search queries** are sent to the Skryx API at search time to
  return matching products.
* **Anonymous shopper interaction events** (searches, page/product views,
  add-to-cart and completed-order events) are sent so Skryx can measure
  search performance and conversion. Events carry a per-session identifier
  only — no names, emails or addresses. Event tracking can be disabled with
  the `skryx_woo_tracking_enabled` filter (return `false`).

The service is operated by Skryx (https://skryx.io):

* Terms of Service: https://skryx.io/terms
* Privacy Policy: https://skryx.io/privacy

== Installation ==

1. Upload the `skryx-woo` folder to `/wp-content/plugins/`
2. Activate via Plugins → Installed Plugins
3. WooCommerce → Skryx Search → paste your keys → Connect

== Frequently Asked Questions ==

= Do I need a Skryx account? =

Yes. Sign up free at https://skryx.io — first 1,000 products + 5,000 searches / month are free.

= What happens if Skryx is down? =

Your store keeps working. The plugin falls back to WordPress default search silently — no broken pages.

= Can I customise the search dropdown? =

Yes — in your Skryx dashboard → Search Widget you control theme, layout, currency display, custom fields, and behaviour.

= How are variable products handled? =

The parent product is indexed as one document with variation attributes (e.g. "Small, Medium, Large") in a searchable field. Searching "scaun Large" still matches.

== Changelog ==

= 1.3.2 =
* Public-release hardening: full unslash + sanitisation pass on all request input, mandatory external-services disclosure added to the readme, plugin version metadata synced across header/constant/readme, and tag list trimmed. No functional change versus 1.3.1.

= 1.3.1 =
* **Fix: logged-in shoppers' cart & order tracking** — server-side events (cart.add, order.completed) from logged-in customers were silently dropped. The fallback session id was `wc-` + the numeric customer id (e.g. `wc-1`, 4 chars), below the ingestion API's 8-char minimum, so events were rejected — and the drainer treated the rejection as success and discarded them. Session ids are now always 8..100 chars (short keys padded with a deterministic hash, so per-customer search↔cart↔order stitching is preserved).
* **Fix: no more silent event loss** — the buffer drainer now re-queues a batch on transient/network failures (ingestion de-dups by event id, so retries are safe) and surfaces validation rejections to the log + last_error instead of discarding them.

= 1.3.0 =
* **Auto-detect store profile** — new Store_Profiler runs at activation/refresh to detect your WC version, theme, checkout type (classic vs Block), payment gateways, brand taxonomy, multi-language plugin, cache plugin, conflict plugins. Plugin behaviour adapts to the detected stack automatically.
* **WC Block Checkout support** — orders placed via the React-based checkout (default on WC 9+) now fire tracker events correctly. Previously only classic shortcode checkout fired.
* **Offline-payment tracking** — COD / bank transfer / cheque orders now emit `order.completed` events. Previously only online gateways (Stripe, PayPal) triggered tracking.
* **Schema drift detection + 1-click recreate** — upgrading the plugin can introduce new field types (e.g. category became string[]). Drift is detected automatically and a "Drop & recreate index" button surfaces in admin to migrate without manual ops.
* **Multi-input widget attach** — widget now binds to ALL search inputs that match the selector (header + sidebar + theme-specific), not just the first. Late-loaded inputs (Flatsome quick-search, Divi slide-in, page builder dynamic search) are caught via MutationObserver.
* **WPML / Polylang multi-language stores** — products are stamped with `language` field on sync so the widget can scope search to the shopper's language.
* **Product type coverage** — grouped / external / subscription / booking products now index correctly. External products link to their external URL, grouped products inherit stock from children, variable products sum variation stock when parent doesn't manage_stock.
* **Multi-brand support** — products with brand terms across multiple plugins (Perfect Brands + native WC 9.6 product_brand + YITH) now index every brand value instead of dropping all but the first.
* **Brand URL params** — search filter intercepts `?pwb-brand=`, `?yith_product_brand=`, `?product_brand=` (third-party brand widgets) and translates to canonical Skryx brand filter.
* **Multi-select category filter** — `?product_cat=a,b` and `?product_cat[]=a&product_cat[]=b` both produce OR filtering.
* **Cache plugin invalidation** — public key rotation flushes WP Rocket / W3 Total Cache / LiteSpeed / WP Super Cache / SiteGround Optimizer / Cloudflare caches, ensuring storefronts pick up the new key immediately.
* **Search plugin conflict detection** — when SearchWP / Relevanssi / Algolia / FacetWP / WOOF / BeRocket is active, plugin steps aside unless explicitly forced via filter. Avoids double-handling search queries.
* **Block theme compatibility** — search-intercept defers to WP's own template resolution on block themes (WC 9.6+ FSE) instead of forcing the classic archive-product.php template.
* **Image size fallback chain** — image_url now walks medium → large → woocommerce_single → full, fixing missing images on stores that re-register custom image sizes.
* **Variation save hook** — admin editing a single variation re-syncs the parent product (previously variant changes weren't propagated).
* **Tracker source filter** — admin-created orders, subscription renewals, REST imports are excluded from `order.completed` events to keep funnel attribution clean.
* **Random_bytes defensive fallback** — hardened PHP setups where /dev/urandom is unreadable no longer crash the OAuth handshake or tracker event IDs.

= 1.2.0 =
* HPOS compatibility declaration
* Server-side event tracker (cart.add, cart.remove, order.completed)
* Sync history (last 10 runs visible in admin)
* Retry failed products button
* Disconnect from Skryx (clears local state, preserves remote index)
* Version migration scaffold
* Bulk-delete drainer (batched API calls instead of N actions)
* Cursor pagination (constant cost per batch on large catalogues)
* Term prefetch (94% reduction in DB queries during sync)
* Sync ETA in progress label
* Re-run Auto-Pilot button
* i18n .pot file
* Persistent test connection status

= 1.1.1 =
* OAuth one-click connect
* Real-time delta sync via WC hooks

= 1.0.0 =
* Initial release

== Upgrade Notice ==

= 1.3.2 =
Recommended for all stores. Restores cart & order tracking for logged-in shoppers and prevents silent loss of tracking events. Safe drop-in upgrade.
