=== QuizMage for WooCommerce ===
Contributors: vasilispapg
Tags: woocommerce, quiz, product finder, elementor, analytics
Requires at least: 6.4
Tested up to: 7.0
Requires PHP: 8.0
Stable tag: 0.1.73
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Requires Plugins: woocommerce

Build interactive product recommenders, personality quizzes, and catalog filters for WooCommerce. Map outcomes to cart actions and track analytics.

== Description ==

**QuizMage for WooCommerce** helps WooCommerce stores run interactive quizzes: weighted product finders, personality outcomes, knowledge tests, and catalog engines. You build quizzes in the admin, embed them with a shortcode or Elementor widgets, match results to real products, and optionally show a finder quiz above the shop or category product grid.

**5 quiz engines are included and fully functional — no license key or payment required.**

Three advanced engines (Bundle / Kit Builder, Budget Router, and Step Configurator) are available through the separately sold **QuizMage Pro add-on**, which is hosted and sold exclusively on [quizmage.vspapg.gr](https://quizmage.vspapg.gr). No code from the Pro add-on is included in this package.

= Free engines (all fully unlocked) =

* **Product Recommender** — Score answers against custom variables; the highest-scoring product wins and is recommended.
* **Personality Quiz** — Multiple-outcome flow; each answer weights one or more outcome cards.
* **Knowledge / Trivia Quiz** — Correct-answer scoring with pass/fail thresholds.
* **Elimination / Filter** — Catalog engine: narrow a tagged product pool by successively eliminating products that fail each answer filter.
* **Attribute Matcher** — Catalog engine: match visitor answers to product attributes and rank the catalog by compatibility.

= Pro add-on engines (requires QuizMage Pro) =

* **Bundle / Kit Builder** — Returns a curated multi-product kit; shoppers see per-row Add to Cart for each item.
* **Budget Router** — Routes visitors to product tiers based on their stated budget.
* **Step Configurator** — Step-by-step product configurator with dependency rules between steps.

= All builds include =

* **WooCommerce integration** — Link quiz outcomes to products; AJAX add to cart on the result step (single product or bundle rows).
* **Shortcode** — Use `[quizmage id="123"]` on any page (replace `123` with your quiz post ID). Legacy aliases `[quizify id="…"]` and `[wooquiz id="…"]` still work.
* **Shop page embed** — *QuizMage → Shop embed*: pick a published quiz, display mode (always expanded, collapsible CTA, or floating button), archive scope, grid sync, and match styling.
* **Shop grid match styling** — After quiz completion, highlight matching products on the shop grid with match percentages. Configure highlight, badge, text, or combinations; accent color; custom labels; and a live preview under *QuizMage → Shop embed → Shop grid match styling*.
* **Shop embed fallbacks** — Shortcode `[quizmage_shop_embed]` and Elementor widget **QuizMage Shop Embed** for themes or page builders that skip WooCommerce loop hooks.
* **Grid sync (shop embed)** — While shoppers answer catalog quizzes, the visible grid narrows via client DOM sync. Auto mode keeps the same page after completion with badges, reorder, and bookmarkable `?qm_products=` / `?qm_tags=` via `history.replaceState`. Server mode reloads the archive for WC query filtering.
* **Theme compatibility (grid sync)** — Three-layer WooCommerce-first stack: (1) optional server product-query filtering; (2) client DOM sync with universal grid scan and AJAX row clone; (3) developer filters (`quizmage_shop_grid_product_ids`, `quizmage_shop_grid_tags`, `quizmage_shop_grid_card_data`). Polylang and WPML product IDs are mapped automatically.
* **Elementor** — **QuizMage for WooCommerce** widget for any page; **QuizMage Shop Embed** widget for archive placement.
* **Design options** — Six layout templates and full theme-style controls (colors, fonts, shadows, progress bar, back-button style — all per-quiz).
* **Analytics dashboard** — Per-quiz KPIs: completions, completion rate, drop-off points, most recommended products, and conversion funnel (Started → Completed → Leads). Date-range filter (7d / 30d / 90d / All time).
* **Email lead capture** — Optional "Get your result" gate; emails, consent, and quiz score stored in a dedicated DB table. One-click CSV export per quiz.
* **Jump / conditional logic** — Branch the quiz flow based on visitor answers.
* **Multi-language** — Run the same quiz in multiple content languages independently of your site language.
* **HPOS & block checkout** — Declares compatibility with WooCommerce custom order tables and cart/checkout blocks.

The storefront UI is built with React; styles are scoped under `.quizmage-app-container` to avoid clashing with your theme. The admin builder is fully responsive down to 360 px viewports. In-admin documentation lives under **QuizMage Quizzes → Documentation**.

= Source code =

The plugin is built from a React (Vite) frontend and a PHP backend. The human-readable JavaScript / JSX source files are included inside this plugin package under `assets/frontend/src/`. The build configuration is at `assets/frontend/vite.config.js` and dependencies are listed in `assets/frontend/package.json`.

To rebuild the compiled assets yourself:

1. `cd assets/frontend`
2. `npm install`
3. `npm run build`

The compiled output is placed in `assets/frontend/dist/`. Third-party libraries included in the compiled bundle are listed in `assets/frontend/package.json`; each library retains its original licence header in the compiled output.

== Installation ==

1. Upload the plugin folder to `/wp-content/plugins/` (or install through **Plugins → Add New → Upload Plugin**).
2. Activate the plugin through the **Plugins** menu in WordPress.
3. Ensure **WooCommerce** is installed and active.
4. Go to **QuizMage Quizzes → Add New**, build a quiz, publish it, then place `[quizmage id="YOUR_ID"]` or the Elementor widget on a page.
5. Optionally visit **QuizMage → Shop embed** to show a quiz above your shop or category product grid.
6. Visit **QuizMage Quizzes → Analytics** to view quiz performance data.

== Frequently Asked Questions ==

= Does this work without WooCommerce? =

No. QuizMage for WooCommerce is built for WooCommerce product mapping and cart actions. WooCommerce must be active.

= How do I show a quiz on the front end? =

Create or edit a **Page**, add a Shortcode block, and paste `[quizmage id="YOUR_QUIZ_ID"]`. Copy the shortcode from the quiz builder top bar or Quick Edit on the quiz list. Alternatively, use the Elementor **QuizMage for WooCommerce** widget on any page.

= How do I embed a quiz on the shop page? =

Go to **QuizMage → Shop embed**, choose a published quiz, and save. If your theme uses standard WooCommerce templates, the quiz appears above the product grid on the shop page (and optionally on category archives). If nothing appears, place `[quizmage_shop_embed]` in an HTML block or use the Elementor **QuizMage Shop Embed** widget.

= What quiz types are included for free? =

Five engines are fully free: **Product Recommender**, **Personality Quiz**, **Knowledge / Trivia Quiz**, **Elimination / Filter**, and **Attribute Matcher**. All five engines include unlimited quizzes, jump logic, lead capture, analytics, and shop embed — no payment or license required.

Three advanced engines (**Bundle / Kit Builder**, **Budget Router**, **Step Configurator**) are available through the separately sold [QuizMage Pro add-on](https://quizmage.vspapg.gr). These engines require the Pro add-on plugin to be installed alongside this free plugin.

= Does this plugin phone home or require a license key? =

No license key is required and all quiz data is stored locally. The plugin makes no external connections except an optional visitor-geolocation lookup used by analytics (see **External Services** below). Optional information about the separately sold Pro add-on may appear under **Settings → QuizMage License**; it does not disable any features in this package.

= How do match highlights work on the shop grid? =

After a shopper completes any quiz from the shop embed, QuizMage stores match rankings in the browser and applies them to products on the archive grid. Configure match appearance — percentage badge, highlight ring, text label, accent color, custom labels — under **Shop grid match styling** on the Shop embed settings page.

= Will grid sync work with my theme? =

Yes, on virtually any WooCommerce theme without a supported-themes allowlist. QuizMage uses a three-layer approach documented under **QuizMage Quizzes → Documentation → Theme compatibility**:

1. **Client (Auto default)** — Scans the full grid container, badges and reorders matches, injects missing ranked products by cloning your theme's existing product row, and updates `?qm_products=` in the URL without reloading.
2. **Server (optional)** — Full page reload with `?qm_products=` or `?qm_tags=` filters the WooCommerce product query on standard shop loops.
3. **Hooks (edge cases)** — Filters such as `quizmage_shop_grid_product_ids` and `quizmage_shop_grid_card_data` for custom catalogs.

Polylang and WPML product IDs in result URLs are translated to the current language automatically.

= Where is the quiz ID? =

Each quiz is a custom post; the numeric **post ID** in the URL or list screen is the value for `id` in the shortcode.

= How does lead capture work? =

Enable the "Lead capture" step in the quiz builder. When a visitor submits their email and ticks the consent box, the data is stored in `wp_quizmage_leads` in your WordPress database. View and export the list from **QuizMage Quizzes → Analytics → Email Leads**.

= Where are analytics events stored? =

Anonymous events (`start`, `progress`, `complete`) go into `wp_quizmage_events`. No PII is stored there. Email leads with scores are stored separately in `wp_quizmage_leads`.

= Can I export the email leads? =

Yes — click **Export CSV** in the Email Leads tab of the Analytics dashboard to download a `.csv` file of the currently filtered leads.

= Is the quiz responsive on mobile? =

Yes. The public quiz shell is mobile-first. The admin builder is fully responsive and tested down to 360 px.

== External Services ==

All quiz data, analytics events, and email leads are stored locally in your WordPress database. The only external service this plugin can contact is an optional IP-geolocation lookup used by the analytics module, disclosed below.

**ip-api.com (visitor geolocation, optional):**
When the analytics module needs to determine a visitor's country, it performs an IP geolocation lookup against `http://ip-api.com`, sending the visitor's IP address. This only happens during quiz interaction events that record analytics data.
Terms of Use / Privacy Policy: https://ip-api.com/docs/legal

**WooCommerce AJAX (same site):**
The "Add to cart" action on the quiz result step calls the standard WooCommerce AJAX endpoint (`/?wc-ajax=add_to_cart`) on your own site. No data is sent to a third party.

**REST API (same site):**
The storefront calls `GET /wp-json/quizmage/v1/quiz/{id}/access` on your own site to confirm quiz availability. This is a same-site request; no data is sent to third parties.

= QuizMage Pro add-on (sold separately — not part of this package) =

If you purchase and install the **QuizMage Pro add-on** from [quizmage.vspapg.gr](https://quizmage.vspapg.gr), that separate plugin connects to the following external services. The Pro add-on code is **not** included in this WordPress.org package.

**Supabase (quizmage cloud analytics & license):**
The Pro add-on sends anonymous quiz event data to a Supabase-hosted backend for cloud analytics sync, and sends license-key verification requests to confirm an active Pro subscription. Data sent includes: quiz ID, event type (start / complete), and a site identifier. No visitor PII is included in analytics events.
* Terms of Service: https://supabase.com/terms
* Privacy Policy: https://supabase.com/privacy

**Stripe (subscription billing):**
When a Pro subscription is purchased or managed from the admin license page, the Pro add-on connects to a Supabase-hosted Edge Function which creates a Stripe Checkout session. Payment is processed entirely by Stripe; no card data passes through your WordPress site or our servers.
* Terms of Service: https://stripe.com/legal/ssa
* Privacy Policy: https://stripe.com/privacy

== Screenshots ==

1. Quiz builder in the WordPress admin.
2. Example quiz on the storefront.
3. Result step with product recommendation and add to cart.
4. Analytics dashboard — hero stats, conversion funnel, and charts.
5. Email Leads tab with score pills, date filter, and CSV export.

== Changelog ==

= 0.1.69 =
* **Shop grid integration fixed** — the WooCommerce shop-page quiz embed, grid match highlighting, and load-more sync now register correctly (previously inactive in installed builds).
* **Analytics accuracy** — quizzes taken in the shop-embed popup are now counted; "vs previous period" comparisons compute correctly; lead events and date ranges use consistent UTC time.
* **Privacy/permissions** — the analytics dashboard and its lead/email actions now require the WooCommerce management capability (previously available to lower roles); the public recommendation endpoint no longer discloses non-published products.
* **Performance** — object-cache layer for recommendation, quiz-payload, and shop-grid rendering with automatic invalidation; schema checks no longer run on every admin request.
* **Data retention** — new opt-in setting to auto-prune old anonymous analytics events (90/180/365 days); lead data is never auto-deleted.
* **Accessibility** — progress bar, question radiogroup (keyboard arrows), step-change focus/announcements, and the shop-embed modal focus trap.

= 0.1.68 =
* **Styling hardening** — display and writing-mode guards plus min-width fixes so quiz layouts render correctly across more themes.
* **Database migrations** — migration logic hardened for schema changes and ZIP-update paths; improved admin error handling.
* **License settings** — refreshed license/settings screens; the free build no longer loads billing scripts.
* **WordPress.org compliance** — fixes for automated plugin-scan errors.

= 0.1.60 =
* **WordPress.org compliance** — Full freemium model: all 5 core quiz engines (Product Recommender, Personality, Knowledge, Elimination Filter, Attribute Matcher) are fully unlocked with no license check or quota. All local feature limits removed (unlimited quizzes, variables, outcomes, questions; jump logic; lead capture; local analytics; shop embed).
* **Pro add-on model** — Three advanced engines (Bundle / Kit Builder, Budget Router, Step Configurator) are now provided by a separately sold Pro add-on plugin. The free plugin shows UI teasers for these engines; their processing code is not included. Detection uses `apply_filters('quizmage_pro_quiz_types_enabled', false)`.
* **Custom CSS removed** — Arbitrary CSS insertion removed from the quiz builder to comply with WordPress.org guidelines. Use the Customizer or your theme's additional CSS for custom styles.
* **Text domain** — All translatable strings now use `quizmage-for-woocommerce` to match the plugin slug.
* **Security hardening** — Nonce checks added to GDPR export download and Stripe checkout session redemption. Input sanitization applied to `$_SERVER` reads, JSON-decoded `$rules` arrays, and raw CSV input.
* **Core file loading** — `wp-admin/includes/upgrade.php` is no longer loaded on every `plugins_loaded` call; it is required only inside the activation routine.
* **SaaS endpoints** — All Supabase / Stripe endpoint constants moved from the free plugin to the Pro add-on, so the WordPress.org build makes no external connections.
* **Tested up to WordPress 6.9.**

= 0.1.43 =
* **Grid sync (Auto) — no reload after quiz** — Auto mode keeps the shopper on the same page: client badges/reorder, inject missing ranked products via theme row clone + AJAX card data, and `?qm_products=` / `?qm_tags=` via `history.replaceState`. Server mode still performs a full reload when explicitly selected.
* **AJAX theme grids** — Full grid container scan; markers on `woocommerce_before_shop_loop_item` and `loop/*` theme templates; runtime markers when only add-to-cart IDs exist.
* **Shop embed persistence** — Quiz results and match rankings restore from localStorage after browser refresh.
* **Match styling** — Highlight ring on product row, badge on thumbnail; hide non-matches for multi-match / dim-grid modes.

= 0.1.40 =
* **Theme compatibility (grid sync)** — Three-layer WooCommerce-first architecture (server query → client DOM → developer hooks). No per-theme allowlist required for most stores.
* **Server grid sync hardening** — Stronger shop-archive detection (Polylang translated shop pages), `post__in` ordering, shortcode/Elementor product query filters, and automatic Polylang/WPML product ID mapping.
* **Client grid sync** — URL bookmark fallback works without localStorage; universal product scan inside `.woocommerce`.

= 0.1.29 =
* **Shop grid match styling** — Configurable match appearance on the WooCommerce product grid after quiz completion. Choose highlight, badge, text, or combined layouts; ring/glow/tint highlights; badge position; accent color; and custom labels. Live admin preview.

= 0.1.26 =
* **Shop embed v2** — Quiz picker, collapsible display mode, archive scope, optional grid dim, and grid sync mode.
* **Shop embed fallbacks** — Shortcode `[quizmage_shop_embed]` and Elementor widget **QuizMage Shop Embed**.
* **Catalog quiz engines** — Elimination/Filter, Attribute Matcher, Bundle/Kit, Budget Tier, and Configurator flows.
* **Analytics** — Optional `source` field on anonymous events (e.g. `shop_embed`).
* **REST** — Public `GET /wp-json/quizmage/v1/quiz/{id}/access` endpoint.

= 0.1.25 =
* Plugin branding consolidated as **QuizMage for WooCommerce**; version and readme aligned for WordPress.org review.
* i18n text domain standardised with translators comments and `languages/` directory scaffold.

= 0.1.16 =
* **Upgrade modal** — correctly identifies the current subscription tier; shows "Current plan" badge and "Manage subscription" link for active plans.
* **Settings → QuizMage License** — redesigned free-build info page with gradient header and direct link to the Pro sales page.
* Backward-compatibility shortcode alias `[wooquiz id="…"]` added.

= 0.1.6 =
* **Analytics dashboard** — date-range filter (7d/30d/90d/All), conversion funnel, email leads table with score %, CSV export, pagination.
* **Lead capture** — email + consent + quiz score persisted to `wp_quizmage_leads`.
* **`do_action('quizmage_lead_submitted', $payload)`** hook for ESP adapter integrations.
* Plugin renamed to **QuizMage for WooCommerce**; prefixes updated from `wooquiz_` to `quizmage_`.

= 0.1.5 =
* Analytics MVP: `wp_quizmage_events` table, event tracking (start, progress, complete, lead).
* Conditional jump / branch logic in quiz answer schema.

= 0.1.4 =
* Initial public release track for WordPress.org packaging.

== Upgrade Notice ==

= 0.1.60 =
Full WP.org compliance release. All feature gates removed — every local feature is now free and unlimited. Custom CSS removed from the builder. If you rely on the Bundle, Budget, or Configurator quiz engines you will need the separately sold QuizMage Pro add-on. No manual database steps required.

= 0.1.43 =
Auto grid sync no longer reloads the shop after quiz completion. No manual database steps required.

= 0.1.40 =
Theme-compatible grid sync with Polylang/WPML ID mapping and URL bookmark support. No manual database steps required.

= 0.1.29 =
Shop grid match styling with live preview and highlight-only post-quiz grid UX. No manual database steps required.

= 0.1.26 =
Shop embed v2, catalog quiz engines, documentation refresh, and same-site REST access check. No manual database steps required.

= 0.1.6 =
Adds persistent email lead storage and a richer analytics dashboard. The `wp_quizmage_leads` table is created automatically on first visit to the Analytics page.

== Privacy ==

QuizMage for WooCommerce stores quiz configuration in your WordPress database (post meta). When email lead capture is enabled and a visitor consents, their email address and quiz score are stored in `wp_quizmage_leads`. This table contains personally identifiable information — ensure your privacy policy discloses this and configure data retention according to your jurisdiction's requirements (GDPR etc.).

Anonymous quiz events (start, progress, completion) are stored in `wp_quizmage_events` with no personally identifiable information. Events may optionally record a short `source` slug (such as `shop_embed`) to distinguish shop-archive sessions from page embeds.

Front-end behavior calls WooCommerce AJAX endpoints on your own site for add-to-cart actions. The storefront calls the same-site REST route `/wp-json/quizmage/v1/quiz/{id}/access` to verify that a quiz remains available before rendering; no off-site transmission occurs in the free plugin.

If you install the separately sold **QuizMage Pro add-on**, please also review its privacy documentation at [quizmage.vspapg.gr/privacy](https://quizmage.vspapg.gr/privacy), as it connects to Supabase and Stripe for cloud analytics and billing.
