{"id":192766,"date":"2024-04-24T05:24:36","date_gmt":"2024-04-24T05:24:36","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/ai-eshop-optimizer\/"},"modified":"2026-05-24T07:20:25","modified_gmt":"2026-05-24T07:20:25","slug":"ai-eshop-optimizer","status":"publish","type":"plugin","link":"https:\/\/ur.wordpress.org\/plugins\/ai-eshop-optimizer\/","author":21057082,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"5.7","stable_tag":"5.7","tested":"7.0","requires":"5.7","requires_php":"7.4","requires_plugins":null,"header_name":"AI eShop Optimizer","header_author":"Oxford Metadata Ltd","header_description":"Boost sales with AI-powered product recommendations. Effortlessly optimize upsells and cross-sells for store success!","assets_banners_color":"5f626f","last_updated":"2026-05-24 07:20:25","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/rooster.systems\/get-aieo\/","header_author_uri":"https:\/\/oxfordmetadata.co.uk","rating":5,"author_block_rating":0,"active_installs":20,"downloads":1889,"num_ratings":2,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","changelog"],"tags":{"1.0":{"tag":"1.0","author":"oxfordmetadata","date":"2025-10-17 04:47:57"},"2.0":{"tag":"2.0","author":"oxfordmetadata","date":"2025-10-17 05:22:32"},"2.1":{"tag":"2.1","author":"oxfordmetadata","date":"2025-10-18 04:09:39"},"3.0":{"tag":"3.0","author":"oxfordmetadata","date":"2025-10-30 22:39:30"},"3.1":{"tag":"3.1","author":"oxfordmetadata","date":"2025-10-30 22:53:26"},"3.1.1":{"tag":"3.1.1","author":"oxfordmetadata","date":"2025-10-31 05:56:05"},"3.1.2":{"tag":"3.1.2","author":"oxfordmetadata","date":"2025-10-31 07:19:41"},"3.1.3":{"tag":"3.1.3","author":"oxfordmetadata","date":"2025-10-31 07:56:29"},"3.2":{"tag":"3.2","author":"oxfordmetadata","date":"2025-11-01 12:45:04"},"3.2.1":{"tag":"3.2.1","author":"oxfordmetadata","date":"2025-11-01 22:53:17"},"3.3":{"tag":"3.3","author":"oxfordmetadata","date":"2025-11-03 11:58:01"},"3.3.1":{"tag":"3.3.1","author":"oxfordmetadata","date":"2025-11-03 21:53:36"},"3.3.2":{"tag":"3.3.2","author":"oxfordmetadata","date":"2025-11-04 14:18:24"},"3.3.3":{"tag":"3.3.3","author":"oxfordmetadata","date":"2025-11-05 12:23:48"},"3.4":{"tag":"3.4","author":"oxfordmetadata","date":"2025-11-06 09:14:22"},"3.5":{"tag":"3.5","author":"oxfordmetadata","date":"2025-11-07 11:25:29"},"3.5.1":{"tag":"3.5.1","author":"oxfordmetadata","date":"2025-11-07 17:10:50"},"3.5.2":{"tag":"3.5.2","author":"oxfordmetadata","date":"2025-11-11 22:07:11"},"3.6":{"tag":"3.6","author":"oxfordmetadata","date":"2025-11-13 03:54:50"},"4.0":{"tag":"4.0","author":"oxfordmetadata","date":"2025-11-27 22:43:29"},"4.1":{"tag":"4.1","author":"oxfordmetadata","date":"2026-02-02 19:19:35"},"4.2":{"tag":"4.2","author":"oxfordmetadata","date":"2026-02-02 19:27:31"},"5.0":{"tag":"5.0","author":"oxfordmetadata","date":"2026-05-20 14:19:10"},"5.1":{"tag":"5.1","author":"oxfordmetadata","date":"2026-05-21 07:57:58"},"5.2":{"tag":"5.2","author":"oxfordmetadata","date":"2026-05-21 12:50:43"},"5.3":{"tag":"5.3","author":"oxfordmetadata","date":"2026-05-22 12:59:19"},"5.4":{"tag":"5.4","author":"oxfordmetadata","date":"2026-05-23 03:58:56"},"5.5":{"tag":"5.5","author":"oxfordmetadata","date":"2026-05-23 10:57:52"},"5.6":{"tag":"5.6","author":"oxfordmetadata","date":"2026-05-23 18:18:00"},"5.7":{"tag":"5.7","author":"oxfordmetadata","date":"2026-05-24 07:20:25"}},"upgrade_notice":[],"ratings":{"1":0,"2":0,"3":0,"4":0,"5":2},"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3076271,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3076271,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3076744,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3076755,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3076755,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{"blueprint.json":{"filename":"blueprint.json","revision":3545919,"resolution":false,"location":"assets","locale":"","contents":"{\"landingPage\":\"\\\/wp-admin\\\/plugins.php\",\"preferredVersions\":{\"php\":\"8.0\",\"wp\":\"latest\"},\"phpExtensionBundles\":[\"kitchen-sink\"],\"features\":{\"networking\":true},\"steps\":[{\"step\":\"installPlugin\",\"options\":{\"activate\":true},\"pluginData\":{\"resource\":\"wordpress.org\\\/plugins\",\"slug\":\"ai-eshop-optimizer\"}},{\"step\":\"login\",\"username\":\"admin\",\"password\":\"password\"}]}"}},"all_blocks":{"aieo\/brand-rails":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"aieo\/brand-rails","version":"1.1.0","title":"AIEO Brand Rails","category":"woocommerce","icon":"category","description":"Stacked curated brand rails (Featured \/ New \/ Your Favourites \/ Top). Each rail has its own count and slides-per-view, configurable in the inspector.","keywords":["aieo","brands","rails","discovery"],"supports":{"html":false,"align":["wide","full"],"spacing":{"margin":true,"padding":true}},"attributes":{"showFeatured":{"type":"boolean","default":true},"showNew":{"type":"boolean","default":true},"showFavourites":{"type":"boolean","default":true},"showTop":{"type":"boolean","default":false},"newMode":{"type":"string","default":"new_product","enum":["new_product","new_brand"]},"topLimit":{"type":"number","default":0},"featuredLimit":{"type":"number","default":0},"newLimit":{"type":"number","default":0},"favouritesLimit":{"type":"number","default":0},"topSlidesPerView":{"type":"number","default":0},"featuredSlidesPerView":{"type":"number","default":0},"newSlidesPerView":{"type":"number","default":0},"favouritesSlidesPerView":{"type":"number","default":0},"limitPerRail":{"type":"number","default":10},"slidesPerView":{"type":"number","default":5}},"render":"file:.\/render.php","editorScript":"file:.\/edit.js","style":"file:.\/style.css","textdomain":"ai-eshop-optimizer"},"aieo\/brand-slider":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"aieo\/brand-slider","version":"1.0.0","title":"AIEO Brand Slider","category":"woocommerce","icon":"slides","description":"Lazy-hydrated brand carousel. Modes: top, new_brand, new_product, favourites (per-user affinity), manual. Server-renders the first N cards as a noscript fallback; client hydrates into a vanilla scroll-snap carousel with arrow nav.","keywords":["aieo","brands","slider","carousel"],"supports":{"html":false,"align":["wide","full"],"spacing":{"margin":true,"padding":true}},"attributes":{"mode":{"type":"string","default":"top","enum":["top","new_brand","new_product","favourites","manual"]},"limit":{"type":"number","default":10},"slidesPerView":{"type":"number","default":5},"title":{"type":"string","default":""},"subtitle":{"type":"string","default":""},"ctaLabel":{"type":"string","default":""},"ctaUrl":{"type":"string","default":""},"manualBrandIds":{"type":"array","default":[]},"showCounts":{"type":"boolean","default":false},"cardStyle":{"type":"string","default":"hero","enum":["hero","logo"]}},"render":"file:.\/render.php","editorScript":"file:.\/edit.js","viewScript":"file:.\/view.js","style":"file:.\/style.css","textdomain":"ai-eshop-optimizer"},"aieo\/brand-azindex":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"aieo\/brand-azindex","version":"1.0.0","title":"AIEO Brand A-Z Index","category":"woocommerce","icon":"list-view","description":"Server-rendered A-Z brand directory. Every letter A\u2013Z (plus '#' for non-Latin brands) is always present; empty letters render disabled. Sticky letter bar + per-letter brand grid with product counts. Reads exclusively from wp_aieo_core_brand_vitals.","keywords":["aieo","brands","a-z","directory","catalogue"],"supports":{"html":false,"align":["wide","full"],"spacing":{"margin":true,"padding":true}},"attributes":{"showCounts":{"type":"boolean","default":true},"showLogos":{"type":"boolean","default":true},"stickyBar":{"type":"boolean","default":true},"headingLevel":{"type":"string","default":"h2","enum":["h2","h3","h4"]},"showHashBucket":{"type":"boolean","default":true}},"render":"file:.\/render.php","viewScript":"file:.\/view.js","editorScript":"file:.\/edit.js","style":"file:.\/style.css","textdomain":"ai-eshop-optimizer"}},"tagged_versions":["1.0","2.0","2.1","3.0","3.1","3.1.1","3.1.2","3.1.3","3.2","3.2.1","3.3","3.3.1","3.3.2","3.3.3","3.4","3.5","3.5.1","3.5.2","3.6","4.0","4.1","4.2","5.0","5.1","5.2","5.3","5.4","5.5","5.6","5.7"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3076322,"resolution":"1","location":"assets","locale":"","width":2682,"height":5862},"screenshot-10.png":{"filename":"screenshot-10.png","revision":3389715,"resolution":"10","location":"assets","locale":"","width":2374,"height":1248},"screenshot-11.png":{"filename":"screenshot-11.png","revision":3389715,"resolution":"11","location":"assets","locale":"","width":2349,"height":1246},"screenshot-12.png":{"filename":"screenshot-12.png","revision":3389715,"resolution":"12","location":"assets","locale":"","width":2348,"height":947},"screenshot-13.png":{"filename":"screenshot-13.png","revision":3388833,"resolution":"13","location":"assets","locale":"","width":662,"height":854},"screenshot-14.png":{"filename":"screenshot-14.png","revision":3388833,"resolution":"14","location":"assets","locale":"","width":653,"height":828},"screenshot-15.png":{"filename":"screenshot-15.png","revision":3388833,"resolution":"15","location":"assets","locale":"","width":666,"height":924},"screenshot-16.png":{"filename":"screenshot-16.png","revision":3388833,"resolution":"16","location":"assets","locale":"","width":657,"height":623},"screenshot-17.png":{"filename":"screenshot-17.png","revision":3388833,"resolution":"17","location":"assets","locale":"","width":661,"height":533},"screenshot-18.png":{"filename":"screenshot-18.png","revision":3388833,"resolution":"18","location":"assets","locale":"","width":663,"height":839},"screenshot-19.png":{"filename":"screenshot-19.png","revision":3388833,"resolution":"19","location":"assets","locale":"","width":658,"height":919},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3076322,"resolution":"2","location":"assets","locale":"","width":2455,"height":1341},"screenshot-20.png":{"filename":"screenshot-20.png","revision":3388833,"resolution":"20","location":"assets","locale":"","width":655,"height":634},"screenshot-21.png":{"filename":"screenshot-21.png","revision":3388833,"resolution":"21","location":"assets","locale":"","width":654,"height":638},"screenshot-22.png":{"filename":"screenshot-22.png","revision":3388833,"resolution":"22","location":"assets","locale":"","width":652,"height":631},"screenshot-23.png":{"filename":"screenshot-23.png","revision":3390442,"resolution":"23","location":"assets","locale":"","width":1990,"height":1244},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3076322,"resolution":"3","location":"assets","locale":"","width":1792,"height":568},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3076322,"resolution":"4","location":"assets","locale":"","width":1791,"height":878},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3076322,"resolution":"5","location":"assets","locale":"","width":2441,"height":593},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3076322,"resolution":"6","location":"assets","locale":"","width":1791,"height":357},"screenshot-7.png":{"filename":"screenshot-7.png","revision":3076322,"resolution":"7","location":"assets","locale":"","width":2435,"height":434},"screenshot-8.png":{"filename":"screenshot-8.png","revision":3380380,"resolution":"8","location":"assets","locale":"","width":1500,"height":732},"screenshot-9.png":{"filename":"screenshot-9.png","revision":3380380,"resolution":"9","location":"assets","locale":"","width":765,"height":1036}},"screenshots":[]},"plugin_section":[],"plugin_tags":[90336,232,16141,148323,250171],"plugin_category":[45],"plugin_contributors":[],"plugin_business_model":[],"class_list":["post-192766","plugin","type-plugin","status-publish","hentry","plugin_tags-ai-chat","plugin_tags-analytics","plugin_tags-content-recommendations","plugin_tags-conversational-ai","plugin_tags-embeddings","plugin_category-ecommerce","plugin_committers-oxfordmetadata"],"banners":{"banner":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/banner-772x250.png?rev=3076755","banner_2x":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/banner-1544x500.png?rev=3076755","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/icon.svg?rev=3076744","icon":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/icon.svg?rev=3076744","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-1.png?rev=3076322","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-2.png?rev=3076322","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-3.png?rev=3076322","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-4.png?rev=3076322","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-5.png?rev=3076322","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-6.png?rev=3076322","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-7.png?rev=3076322","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-8.png?rev=3380380","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-9.png?rev=3380380","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-10.png?rev=3389715","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-11.png?rev=3389715","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-12.png?rev=3389715","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-13.png?rev=3388833","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-14.png?rev=3388833","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-15.png?rev=3388833","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-16.png?rev=3388833","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-17.png?rev=3388833","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-18.png?rev=3388833","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-19.png?rev=3388833","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-20.png?rev=3388833","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-21.png?rev=3388833","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-22.png?rev=3388833","caption":""},{"src":"https:\/\/ps.w.org\/ai-eshop-optimizer\/assets\/screenshot-23.png?rev=3390442","caption":""}],"raw_content":"<!--section=description-->\nAI eShop Optimizer - AI Chat &amp; Content Recommendations Plugin\n\n<p>Welcome to AI eShop Optimizer, the premier AI-driven solution for intelligent customer engagement powered by the latest AI models from Anthropic and OpenAI.<\/p>\n\n<p><strong>Works with or without WooCommerce<\/strong> - Perfect for:\n- E-commerce sites with WooCommerce for product recommendations\n- Corporate and content sites for intelligent chat assistance\n- Merchant information sites that need AI-powered customer support<\/p>\n\n<p>The plugin provides advanced AI chat capabilities with semantic search powered by state-of-the-art embedding engines. For WooCommerce sites, it also enables product recommendations through our graph-database powered service at https:\/\/eshop-optimizer.com.\nOur advanced AI tools uncover latent patterns and consumer preferences, empowering you with strategic upsell and cross-sell propositions.\nThe plugin also enables you to import with one click our recommendations - or any product recommendations in a csv file that conforms to our format - and to also monitor their performance using google UTM tags (which you may also use to monitor your own recommendations performace).<\/p>\n\n<h3>Features<\/h3>\n\n<h3>AI Product Recommendations<\/h3>\n\n<ul>\n<li>Harness the power of a semantic graph database for unmatched product pairing suggestions.<\/li>\n<li>Dive deep into your sales data to extract bespoke upsell and cross-sell opportunities.<\/li>\n<li>Beta-test participants reported a remarkable 57%+ annual surge in sales.<\/li>\n<li>Privacy-centric: Opt out of sharing product and category names and product prices with limited impact to the quality of the recommendations.<\/li>\n<li>Effortlessly back up and export current Upsells and Cross-sells.<\/li>\n<li>Leverage Google GA4 insights to gauge the success of your recommended pairings.<\/li>\n<\/ul>\n\n<h3>Products for the Same Needs<\/h3>\n\n<ul>\n<li>Automatically recommend products that fulfill the same customer needs<\/li>\n<li>Uses your product's need attributes (pa_need taxonomy) to find matching products<\/li>\n<li>Ranks suggestions by pre-computed sales performance from the product catalogue<\/li>\n<li>Intelligently excludes existing upsells and cross-sells to avoid duplicates<\/li>\n<li>Stores up to 6 optimized suggestions per product for fast retrieval<\/li>\n<li>Displays prominently on product pages (appears first, before other recommendations)<\/li>\n<li>Multi-tier caching for optimal performance (Object Cache + Database)<\/li>\n<li>Generate suggestions as part of Operational Efficiency workflow<\/li>\n<\/ul>\n\n<h3>Insights Chat \u2014 Claude-powered (NEW in 5.0)<\/h3>\n\n<ul>\n<li>Ask your shop questions in plain language from inside the WordPress admin<\/li>\n<li>Powered by the AI Chat Anthropic key you already have \u2014 no separate subscription<\/li>\n<li>33 purpose-built Claude data abilities resolved automatically via the WordPress Abilities API<\/li>\n<li>11 categorized accordion groups of suggestion chips \u2014 Customers, Brand portfolio, Recommendation rails, Attribution &amp; archives, Product needs audit, Star ratings, Content &amp; blog, Cross-skill, Store analytics, Promotions \/ launches \/ sales, Newsletters &amp; campaigns<\/li>\n<li>Cross-cuts orders, products, attribution, recommendations, ratings, blog engagement, and customer profiles<\/li>\n<li>Stays inside WooCommerce \u2014 no third-party BI subscription, no data export<\/li>\n<\/ul>\n\n<h3>Joint Session \u00d7 Attribution Analytics (NEW in 5.0)<\/h3>\n\n<ul>\n<li>Bridge between the Session Tracker (engagement) and the Attribution Engine (conversion) \u2014 both keyed off the same aieo_session_id cookie<\/li>\n<li>Blog-post attribution \u2014 clicks from blog posts to products now attribute correctly with the originating post_id<\/li>\n<li>Engagement-bucket buy-probability \u2014 empirical P(cart-add) per (scroll-quartile \u00d7 time-quartile \u00d7 mouse-activity) bucket per product<\/li>\n<li>Abandoned-cart triage, cart-removal analysis, rating \u00d7 conversion correlation, need \u00d7 conversion correlation<\/li>\n<li>Pre-aggregated daily rollup tables keep chat answers in single-digit milliseconds regardless of history depth<\/li>\n<\/ul>\n\n<h3>Insights Remote DB Streaming (NEW in 5.0, Pro)<\/h3>\n\n<ul>\n<li>Stream raw analytics events to your own operator-owned MariaDB \/ MySQL for unbounded BI access<\/li>\n<li>Reuses the existing ERP connection registry \u2014 same encrypted credentials, same audit trail<\/li>\n<li>Configurable export frequency (15 min \/ hourly \/ daily) with per-table lag dashboard<\/li>\n<li>Local-purge failsafe \u2014 hot rows are not deleted until the remote confirms receipt<\/li>\n<li>Net stable local database footprint ~1.1 GB year-over-year<\/li>\n<\/ul>\n\n<h3>Star Ratings \u2192 SEO Schema (NEW in 5.0)<\/h3>\n\n<ul>\n<li>AggregateRating JSON-LD automatically bridged into AIOSEO, Yoast, and RankMath via their schema filters<\/li>\n<li>Fallback head-injected JSON-LD when no SEO plugin is detected<\/li>\n<li>Per-feature enable\/disable toggle on the Star Ratings admin page<\/li>\n<li>Surface customer ratings to Google Rich Results without manually configuring each SEO plugin<\/li>\n<\/ul>\n\n<h3>Custom Slots + Tolstoy + Recommendations Ordering (NEW in 5.1)<\/h3>\n\n<ul>\n<li>Drag-and-drop \"Recommendations Ordering\" card on the e-shop Manager dashboard reorders every recommendation rail (Up-sells \/ Cross-sells \/ Related \/ Recently Viewed \/ Products for the same needs) and any operator-defined Custom Slot, with a per-row Show toggle to hide rails without removing them<\/li>\n<li>Custom Slots host arbitrary content alongside the built-in reco rails \u2014 two kinds per slot:\n\n<ul>\n<li>Tolstoy: paste a widget id + account UUID; AIEO assembles the <code>&lt;tolstoy-widget&gt;<\/code> tag and defer-loads the gotolstoy.com CDN script once per page<\/li>\n<li>HTML \/ code: rich-text WYSIWYG (TinyMCE) with a Code tab, accepts any HTML, embed scripts, image tags, or WooCommerce shortcodes (e.g. <code>[products limit=\"6\" orderby=\"popularity\"]<\/code>)<\/li>\n<\/ul><\/li>\n<li>Per-slot title with show\/hide toggle \u2014 renders with the same heading + underline styling as the built-in \"Recently Viewed Products\" \/ \"Related Products\" titles<\/li>\n<li>Cross-tab Tolstoy attribution \u2014 clicks from a Tolstoy carousel that lead to a cart-add are recorded as <code>source='tolstoy'<\/code> in wp_aieo_addcart_events with <code>source_meta = {slot_id, tolstoy_widget_id, clicked_url}<\/code> so reports can pivot on widget, carousel, or source product<\/li>\n<li>Works on BOTH FSE block themes (via the <code>.ff-recommendations-cluster<\/code> flex container + inline CSS <code>order:<\/code> rules) AND classic themes (via dynamic re-prioritisation of WooCommerce <code>woocommerce_after_single_product_summary<\/code> action hooks)<\/li>\n<\/ul>\n\n<h3>IAPI (Interactivity API) \u2014 WC Cart \/ Checkout block parity (NEW in 5.1)<\/h3>\n\n<ul>\n<li>Full integration with the modern WooCommerce block-based cart and checkout (driven by WordPress @wordpress\/interactivity)<\/li>\n<li>Side-cart, Swatches multi-select, Sticky Add-to-Cart, Wishlist, Star Ratings, Free-Shipping Display, Recommendations attribution all work on both surfaces \u2014 block-cart\/block-checkout AND legacy shortcode-cart\/shortcode-checkout<\/li>\n<li>AIEO_DMM_Swatches_Runtime supports dual-mode enqueue (<code>@aieo\/swatches-iapi<\/code> module when IAPI is on, jQuery bundle otherwise) with a single DOM contract<\/li>\n<li>WC Store API (<code>wc\/store\/cart<\/code>) endpoints recognised by the side-cart, attribution log, and waitlist subscribe flows so block-checkout actions are captured the same as classic checkout<\/li>\n<li>AIEO Custom Slots, Free-Shipping Display, and Trust Badges register their bridge-block render paths inside <code>woocommerce_blocks_loaded<\/code> so they're available in block-themed cart\/checkout templates via the Site Editor<\/li>\n<\/ul>\n\n<h3>Floating Mini-Cart + Free-Shipping Bar (NEW in 5.0)<\/h3>\n\n<ul>\n<li>Two-column floating mini-cart styled after the Rey theme \u2014 left column recommends \"You might like\", right column shows Shopping Bag \/ Recently Viewed<\/li>\n<li>Free-shipping progress bar right under the tab header<\/li>\n<li>500 ms debounced quantity AJAX \u2014 qty changes feel instant, no full cart recalculation on the server<\/li>\n<li>Session-level HTML cache (30 s TTL); WC fragments integration keeps every other widget in sync<\/li>\n<li>Sticky Add-to-Cart bar for product pages<\/li>\n<\/ul>\n\n<h3>Pricing Engine + Conversion Boosters (NEW in 5.0)<\/h3>\n\n<ul>\n<li>Per-role price overrides via CSV upload, with batch validation<\/li>\n<li>Brand-level % discounts with start\/end-date windows<\/li>\n<li>Loyalty class definitions + per-user assignments<\/li>\n<li>Stacking recipe: Role Pricing \u2192 Brand Discount \u2192 Loyalty Class \u2014 each customer sees the strongest applicable price<\/li>\n<li>Brand-based free-gift offers (cart subtotal threshold per brand)<\/li>\n<li>Configurable exit-intent modal with checkout-specific variant<\/li>\n<\/ul>\n\n<h3>Marketplace Connectors &amp; Shipping (NEW in 5.0)<\/h3>\n\n<ul>\n<li>Marketplace Order Importer \u2014 Skroutz \/ e-shop \/ Amazon orders flow into WooCommerce as native orders so attribution, stock, customer profiles, and fulfillment stay unified<\/li>\n<li>Per-vendor rotatable webhook tokens + configurable SKU lookup strategy<\/li>\n<li>Streaming marketplace feed generator (XML \/ CSV) for 35k-product catalogues<\/li>\n<li>Greek + Cypriot Shipment Tracking providers (replaces the WC plugin's US\/UK\/Canada\/Germany defaults)<\/li>\n<li>Smart Shipping Label \u2014 postcode-less carts see \"Carrier (\u0391\u03c0\u03cc \u20acX.XX)\" minimum rate so customers know shipping isn't free without seeing a misleading default<\/li>\n<\/ul>\n\n<h3>Customer Intelligence + Web Push (NEW in 5.0)<\/h3>\n\n<ul>\n<li>wp_aieo_customer_intelligence keyed by eponymous_id \u2014 omnichannel customer view (eshop + in-store) is the single source of truth<\/li>\n<li>Behavioural segments \u2014 Top customers, Lost cohort, Lookalikes, Abandoned-cart, reactivation<\/li>\n<li>Triggered web-push flows \u2014 welcome, reactivation, price-drop, back-in-stock \u2014 with full dispatch log + click attribution<\/li>\n<li>Customer Survey Intelligence \u2014 Gravity Forms ingest + 7 high-signal metrics (NPS class, satisfaction, priorities, discovery channel, gift preferences, personal profile) + composite VoC score<\/li>\n<li>\"Notify me when back in stock\" Waitlist with automatic stock-watcher emails<\/li>\n<li>Wishlist analytics \u2014 most-wishlisted products, surfaces, and pages driving adds<\/li>\n<\/ul>\n\n<h3>AI-Powered Chat (FREE)<\/h3>\n\n<ul>\n<li><strong>Support for latest AI models from Anthropic Claude and OpenAI:<\/strong>\n\n<ul>\n<li>Claude Opus 4.1, Claude Sonnet 4.5, Claude Haiku 4.5<\/li>\n<li>GPT-5, GPT-4, GPT-o1, GPT-3.5<\/li>\n<\/ul><\/li>\n<li><strong>Advanced embedding engines for semantic product search:<\/strong>\n\n<ul>\n<li>Voyage AI: voyage-3.5-large, voyage-3.5-lite, voyage-3-lite, voyage-finance-2<\/li>\n<li>OpenAI: text-embedding-3-large, text-embedding-3-small, text-embedding-ada-002<\/li>\n<\/ul><\/li>\n<li>Customizable chat templates for different use cases<\/li>\n<li>Smart product search and recommendations powered by AI embeddings<\/li>\n<li>Product catalog integration with semantic similarity matching<\/li>\n<li>Context-aware responses using customer behavior data<\/li>\n<li>Customizable chat appearance with multiple themes (Rounded\/Square)<\/li>\n<li>Dynamic color customization for branding<\/li>\n<li>Session management and chat history tracking<\/li>\n<li>Floating chat widget with adjustable positioning<\/li>\n<li>Mobile-responsive design<\/li>\n<\/ul>\n\n<h3>Advanced Session Analytics<\/h3>\n\n<ul>\n<li><strong>Custom Class-Based Event Tracking<\/strong> - Track clicks on any element using custom CSS selectors<\/li>\n<li><strong>Click Event Throttling<\/strong> - Prevent database flooding while maintaining accurate click counts<\/li>\n<li><strong>Cookie Consent Bypass Mode<\/strong> - Toggle GDPR compliance for immediate tracking or compliance-first approach<\/li>\n<li><strong>Product Image Click Tracking<\/strong> - Special tracking for product images with debounce to prevent duplicate events<\/li>\n<li><strong>Anti-Double-Counting<\/strong> - Custom rules take precedence over standard tracking<\/li>\n<li><strong>Automatic Cache Busting<\/strong> - Version strings with variable lengths for aggressive cache invalidation<\/li>\n<li><strong>Multi-Layer Cache Compatible<\/strong> - Works with Nginx, Varnish, REDIS, WP Rocket, Cloudflare<\/li>\n<\/ul>\n\n<h3>How to Use<\/h3>\n\n<ul>\n<li><p>Export and Back-Up Current Pairings\nSafely export existing upsells and cross-sells, which doubles as a reliable back-up. The Pro version also takes your current selections into account, potentially enhancing the AI's output.<\/p><\/li>\n<li><p>Accelerated Order Export (Enabled HPOS Required)\nSwiftly export up to 100,000 order items. The Pro version lifts the cap on orders, including comprehensive details like Order ID, Product ID, sequence, and more.\nExclude product titles and prices at will.\nMaintain customer anonymity by withholding CustomerIDs, albeit with a slight compromise on recommendation precision.\nOpt for a seasonal sales analysis, focusing on trends pertinent to the current time of year.\nRefine Your Data with Our AI Engine\nRegister at eshop-optimizer.com and submit your data. Within moments, receive refined upsell and cross-sell strategies for your leading products. Full catalog analysis available with the Pro version.\neshop-optimizer.com respects your privacy and adheres to strick privacy guidelines. Our company's, Oxford Metadata Ltd, privacy provisions has been approved by both Google and Facebook. For further details please visit: https:\/\/eshop-optimizer.com\/compliance<\/p><\/li>\n<li><p>Import Tailored Upsell and Cross-sell Strategies\nImplement the AI-crafted upsell and cross-sell suggestions via an easy-to-upload CSV file.<\/p><\/li>\n<li><p>Witness Enhanced Sales\nMarvel at the accuracy of our AI-driven recommendations and observe how they can boost your sales figures. We're so confident in our service that we offer free initial analyses - we believe you'll be eager for more and enthusiastic to spread the word!\n  Experience the relevance of our recommendations and discover how AI can improve your store's sales. We offer free analyses, and we are confident that you'll want more and share our plugin with your friends!<\/p><\/li>\n<\/ul>\n\n<p>For any queries or support, contact us at <a href=\"mailto:support@eshop-optimizer.com\">support@eshop-optimizer.com<\/a>.<\/p>\n\n\n\n<p>Website: (https:\/\/eshop-optimizer.com)<\/p>\n\n<!--section=installation-->\n<p>Extract the contents of this plugin zip file into your wp-content\/plugins\/ directory locally.\nUpload the extracted folder to your website.\nNavigate to wp-admin\/plugins.php on your dashboard.\nFind 'AI eShop Optimizer' and activate the plugin.\nAlternatively, install directly through WordPress:<\/p>\n\n<p>Go to the 'Plugins' menu in WordPress.\nClick 'Add New' and search for 'AI eShop Optimizer.'\nInstall and activate directly from your dashboard.<\/p>\n\n<!--section=changelog-->\n<h4>5.7 - 2026-05-24<\/h4>\n\n<p><strong>Day-after follow-up to 5.6 \u2014 runtime-only brand blocks, engagement-gated Web Push, plus three small admin polish items<\/strong><\/p>\n\n<p><strong>Web Push \u2014 engagement-gated banner (Chrome quiet-UI mitigation)<\/strong>\n* NEW: the opt-in banner no longer mounts on a flat <code>setTimeout(SHOW_DELAY_MS)<\/code>. It now waits for AIEO Session Tracker to dispatch an <code>aieo:engagement<\/code> CustomEvent on <code>document<\/code> at one of these milestones: <code>pageviews-2<\/code>, <code>pageviews-3<\/code>, <code>scroll-25<\/code>, <code>scroll-50<\/code>, <code>scroll-75<\/code>, <code>add-to-cart<\/code>, <code>time-30s<\/code>. The \"Show delay (ms)\" admin setting becomes a minimum-wait floor (banner never appears before that even if scroll fires at 2s)\n* NEW: hard-cap fallback at 90s \u2014 visitors who never hit a milestone but also don't bounce still see the banner eventually\n* Graceful degradation: when AIEO Session Tracker is absent (operator disabled it OR runtime-only install without the admin asset), falls back to the original flat-timeout behavior so no install regresses\n* Why this matters: Chrome's <a href=\"https:\/\/developer.chrome.com\/blog\/quieter-permission-ui-for-notifications\/\">quieter notification permission UI<\/a> auto-denies prompts on domains with low acceptance rates. Asking bounce visitors on first-page-load poisons the reputation \u2014 every silent auto-denial counts as a \"Block\" signal. By only prompting engaged visitors, the acceptance rate per prompt climbs and Chrome's quiet UI fires less aggressively over time\n* Engagement signal source: <code>AIEO_SESSION_TRACKER.pageViewsInSession<\/code> (new public property, sessionStorage-backed, incremented eagerly even for bounce visitors so counts are accurate). New <code>aieo:engagement<\/code> CustomEvent is also dispatched from inside <code>trackAddToCart<\/code> and <code>trackScrollDepth<\/code> so other consumers can hook in too \u2014 no new tracker, just extends what's already there<\/p>\n\n<p><strong>Brand blocks now runtime-resolvable \u2014 admin plugin no longer required for storefront pages that render <code>aieo\/brand-*<\/code><\/strong>\n* NEW: <code>AIEO_Runtime_Brand_Blocks<\/code> delegate in the runtime plugin registers the six brand-related server-rendered blocks (<code>aieo\/brand-azindex<\/code>, <code>brand-slider<\/code>, <code>brand-rails<\/code>, <code>brand-related<\/code>, <code>brand-archive-hero<\/code>, <code>brand-story<\/code>) at <code>init<\/code> priority 29 so they're available even when the admin plugin isn't in the request's plugin whitelist. block.json + render.php files stay in the admin plugin's directory (single source of truth); <code>AIEO_Core_Brand_Vitals<\/code> autoloads via the mu-plugins autoloader regardless of admin being active\n* <code>AIEO_Blocks_Loader::register_blocks()<\/code> now consults <code>WP_Block_Type_Registry::is_registered()<\/code> before each <code>register_block_type()<\/code> call \u2014 when both plugins are active the runtime registration at init@29 wins, and admin's loop at init@30 silently skips already-registered blocks (no more <code>_doing_it_wrong<\/code> notices from duplicate registration)\n* Shared style handle <code>aieo-article-cards<\/code> (needed by brand-related) is also registered by the runtime delegate so brand-related renders correctly in runtime-only mode\n* Use case: pages with brand sliders \/ brand A-Z directory \/ related-brands rails on category, blog, and landing pages no longer require the full admin plugin on every request \u2014 same render output, ~40 ms saved per page on cold-cache fetches<\/p>\n\n<p><strong>Fix \u2014 Session Tracker JS 404 + MIME-type refusal on every front-end page<\/strong>\n* Fixed: <code>aieo-session-tracker.js<\/code> returned HTTP 404 with <code>text\/html<\/code> body because the class was moved to the runtime plugin (Phase 1.5) but the JS asset was left behind in the admin plugin. <code>plugin_dir_url(__FILE__) . '..\/assets\/js\/aieo-session-tracker.js'<\/code> from the runtime class resolved to <code>runtime\/assets\/js\/aieo-session-tracker.js<\/code> \u2014 which didn't exist. Browsers logged \"Refused to execute script from ... because its MIME type ('text\/html') is not executable\" on every page load. The asset now ships alongside both plugin copies of the class so the runtime-first autoloader path finds its own asset<\/p>\n\n<p><strong>Critical fix \u2014 Web Push: opt-in pipeline broken by deferred JS + Service-Worker 404 + silent localStorage throws<\/strong>\n* Fixed: <code>AIEO_DMM_Web_Push<\/code> now registers <code>rocket_delay_js_exclusions<\/code> on activation so WP Rocket's \"Delay JavaScript execution\" feature stops treating <code>aieo-push-optin<\/code>, <code>aieoPush<\/code>, <code>aieo-push-sw<\/code> and <code>aieo-magic-link-modal<\/code> as deferred-until-interaction scripts. Without this, the opt-in banner JS only ran after a mouse-move \/ scroll \/ click that lands inside the page \u2014 bots, remote-desktop sessions, and visitors who follow a deep link straight to a product page never triggered it, so the subscribe POST never fired. Now Just Works on every install with no operator config\n* Fixed: <code>aieo-push-optin.js<\/code> silently died on Edge's Tracking Prevention (and Safari ITP) when <code>localStorage.getItem()<\/code> threw \u2014 the unguarded call killed the entire IIFE before the banner could even render. Now wrapped in try\/catch; blocked storage is treated as \"no cooldown set\" so the banner still appears\n* NEW: silent re-subscribe path \u2014 when <code>Notification.permission === 'granted'<\/code> from a prior visit but no <code>wp_aieo_push_subscriptions<\/code> row exists (e.g. the earlier SW-404 bug killed the original POST), the JS now silently registers the SW, calls <code>pushManager.subscribe()<\/code> and POSTs the result on page load. No banner re-prompt, no operator action \u2014 historical \"granted but never recorded\" users heal themselves on next visit\n* Improved: <code>postSubscription()<\/code> now checks <code>response.ok<\/code> and throws on non-2xx so the outer try\/catch records the failure instead of fire-and-forget. CFG.debug-gated console output for the operator who wants to dig in\n* See <a href=\"docs\/WEB_PUSH_INSTALL.md\">docs\/WEB_PUSH_INSTALL.md \u00a74<\/a> for the Nginx <code>location = \/aieo-push-sw.js<\/code> block \u2014 the third leg of this trio (404 SW URL was the upstream root cause on the FF prod incident 2026-05-23)<\/p>\n\n<p><strong>Data Prep Schedule \u2014 <code>product_attributes<\/code> stage added so brand blocks self-populate without the manual rebuild<\/strong>\n* NEW: hourly data-prep cron now runs a <code>product_attributes<\/code> stage between <code>category_hierarchy<\/code> and <code>product_vitals<\/code>. This stage calls the <code>AIEO_InsertCoreProductAttributes<\/code> stored procedure with the operator's configured brand \/ vendor \/ size \/ color attribute taxonomies \u2014 resolving parent <code>brand_id<\/code> from <code>wp_term_relationships<\/code>. The existing <code>propagate_brand<\/code> stage then copies parent \u2192 variations as before\n* Why it matters: brand blocks (<code>aieo\/brand-azindex<\/code>, <code>brand-slider<\/code>, <code>brand-rails<\/code>, <code>brand-related<\/code>, <code>brand-archive-hero<\/code>, <code>brand-story<\/code>) used to render empty on sites where the operator hadn't ticked \"Please recreate the product core attributes and principal categories\" in the Operational Efficiency Settings UI. That checkbox is now correctly scoped as a manual intervention only \u2014 the hourly schedule covers the day-to-day case\n* Defensive: the new stage uses <code>information_schema.ROUTINES<\/code> to verify the SP exists before CALLing it \u2014 older installs without the SP get a clean no-op instead of breaking the whole tick<\/p>\n\n<p><strong>Google Reviews \u2014 single-location auto-fallback + clearer empty states<\/strong>\n* NEW: when the <code>aieo\/google-reviews<\/code> block (or <code>[aieo_google_reviews]<\/code> shortcode) is in \"Single location\" mode but no slug is set AND the page can't auto-resolve a location from context, the block now falls back to the operator's only configured location if exactly one exists. Most SMB stores have a single physical shop \u2014 they no longer need to pick a slug for every block instance, the block just works\n* Improved: the empty-state message now shows the actual number of locations configured and steers the operator to the right next step. \"No Google Reviews locations configured yet \u2014 add one under...\" (when 0 exist) vs \"You have N locations configured \u2014 pick one via the block's sidebar, or switch to All-locations \/ Cards grid mode\" (when 2+ exist). Replaces the old cryptic \"Set a location slug, or place this block on a page bound to a location row\"\n* The admin Settings tab now carries a full \"How to display the reviews on the storefront\" help card explaining the FSE block, the three shortcodes, all 11 attributes, and a <code>do_shortcode()<\/code> PHP-template snippet \u2014 so operators on classic themes \/ page builders find the docs without leaving the admin<\/p>\n\n<p><strong>Google Reviews \u2014 shortcodes for non-FSE themes + runtime-only exposure<\/strong>\n* NEW: <code>[aieo_google_reviews]<\/code> shortcode \u2014 wraps the same render path the <code>aieo\/google-reviews<\/code> block uses, so classic themes \/ widget areas \/ page-builder pages can drop in Google Reviews without needing FSE block-template editing. Single-location mode when a <code>location<\/code> attribute is supplied (<code>[aieo_google_reviews location=\"downtown\"]<\/code>), all-locations mixed-feed otherwise (<code>[aieo_google_reviews]<\/code>). All block attributes are exposed in snake_case: <code>min_rating<\/code>, <code>max_count<\/code>, <code>layout<\/code> (grid\/list\/carousel), <code>presentation<\/code> (static\/slider\/rotator), <code>autoplay_sec<\/code>, <code>show_overall<\/code>, <code>show_rate_us<\/code>, <code>show_maps_button<\/code>, <code>heading<\/code>, <code>mode<\/code> (single\/all_mixed\/cards_grid)\n* NEW: <code>[aieo_google_locations_grid]<\/code> shortcode \u2014 convenience alias forced to <code>mode=\"cards_grid\"<\/code> for the per-location cards layout. Accepts the same attributes\n* Single source of truth: both shortcodes call <code>AIEO_Google_Reviews_Block::render()<\/code> directly, so the cache, the markup, and the CSS handle are identical to the block output \u2014 operators can mix-and-match blocks (FSE) and shortcodes (classic) on the same site without divergent rendering\n* NEW: <code>AIEO_Runtime_Google_Reviews<\/code> delegate exposes the block + shortcodes to runtime-only contexts \u2014 admin's <code>AIEO_DMM_Google_Reviews<\/code> module is no longer required on the frontend. block class files stay in admin's <code>includes\/dmm\/google-reviews\/<\/code> (single source of truth); the mu-plugins autoloader resolves them on demand. The block class is now idempotent (<code>AIEO_Google_Reviews_Block::register()<\/code> guarded by a <code>$registered<\/code> flag) and admin's call is gated behind <code>! defined( 'AIEO_RUNTIME_OWNS_AJAX' )<\/code> so runtime is exclusive when both plugins are active. Same <code>aieo\/store-info<\/code> block also exposed<\/p>\n\n<p><strong>Data Prep Schedule<\/strong>\n* NEW: <code>product_attributes<\/code> stage runs hourly between <code>category_hierarchy<\/code> and <code>product_vitals<\/code> \u2014 calls <code>AIEO_InsertCoreProductAttributes<\/code> automatically so parent <code>brand_id<\/code> populates without ticking the manual \"Recreate product core attributes\" checkbox\n* NEW: per-stage Notes column in the Last-run table \u2014 shows useful metrics per stage (e.g. \"4921 \/ 13513 with brand \u00b7 194 distinct brands\")<\/p>\n\n<p><strong>Admin polish<\/strong>\n* Fixed: Database Performance Optimization card no longer hardcodes \"MariaDB 11.4+ detected!\" \/ \"MySQL 8.0+ detected!\" \u2014 now interpolates the actual detected version from <code>aieo_check_mariadb_version()<\/code> (e.g. \"MariaDB 11.8.7 detected!\"). Falls back to the prior threshold strings if <code>version_number<\/code> is somehow missing\n* Fixed: Google Reviews \u2192 Locations admin no longer uses Femme-Fatale-specific placeholder text (<code>piraeus<\/code> slug, <code>Femme Fatale \u03a0\u03b5\u03b9\u03c1\u03b1\u03b9\u03ac\u03c2<\/code> display name). All four placeholders are now generic + translatable (<code>e.g. main-store, downtown, branch-2<\/code>, <code>Customer-facing label for this location<\/code>, etc.) so the form isn't shipping client-branded examples<\/p>\n\n<h4>5.6 - 2026-05-23<\/h4>\n\n<p><strong>Same-day follow-up to 5.5 \u2014 Fulfillment UX polish + two production hotfixes + CSV round-trip cleanup<\/strong><\/p>\n\n<p><strong>Production hotfixes<\/strong>\n* Hotfix: <code>Undefined constant \"AIEO_VERSION\"<\/code> fatal in <code>AIEO_Wishlist::enqueue_assets()<\/code> on category pages when AIEO Runtime loads before the main plugin's constant definition. Defensive <code>defined()<\/code> fallback chain in the runtime: <code>AIEO_VERSION<\/code> \u2192 <code>AIEO_RUNTIME_VERSION<\/code> \u2192 <code>'0.0.0'<\/code>. Same pattern for <code>AIEO_FILE<\/code>. Surfaced on prod femme-fatale.gr <code>\/me-ammonia\/<\/code> as a site-wide HTTP 500 immediately after the 5.5 upgrade\n* Performance: new <code>AIEO_Perf::strip_aioseo_product_schema_on_archives()<\/code> short-circuits AIOSEO Pro's Product \/ WooCommerceProduct \/ Offer \/ AggregateOffer schema graphs on archive and taxonomy pages. AIOSEO was iterating every product in the loop and calling <code>$product-&gt;get_available_variations()<\/code>, which on Iconic Variation Swatches triggers a <code>$wpdb-&gt;get_results()<\/code> per variation \u2014 ~900 queries per render on a 15-variable-product category. Single-product pages are unaffected (full JSON-LD still emitted where Google rich results actually matter). Prod render time on <code>\/me-ammonia\/<\/code>: 9.4s \u2192 3.2s<\/p>\n\n<p><strong>Fulfillment \u2014 order-edit meta box<\/strong>\n* Fixed: Add Voucher carrier dropdown was showing every registered carrier including disabled ones. Now filters to operator-enabled carriers + custom carriers only (matches the rest of the admin)\n* Fixed: pressing Enter in the tracking-number input was submitting the order's outer form, navigating to the \"Downloaded products\" panel. The AIEO meta-box inputs now suppress Enter and trigger the explicit Save button instead\n* Improved: ACS (and any carrier already mapped via <code>get_carrier_for_order()<\/code>) is pre-selected when the modal opens, instead of defaulting to the alphabetical-first carrier\n* Improved: button labels now reflect what will actually happen \u2014 \"Save tracking\" \/ \"Generate voucher\" by mode, with a paired \"Save + mark completed\" \/ \"Generate voucher + mark completed\" for the common single-click flow\n* Fixed: custom carriers with <code>create_mode = 'manual'<\/code> (no API integration) no longer error with \"driver does not support create_voucher\". The manual flow now persists the tracking number directly and fires the customer email, bypassing the driver call<\/p>\n\n<p><strong>Fulfillment \u2014 Carriers without API admin<\/strong>\n* NEW: inline Edit button next to Remove on every row \u2014 label and tracking-URL template editable in place; Save \/ Cancel pair posts to the same upsert AJAX endpoint\n* Fixed: <code>tracking_url_template<\/code> field was being silently ignored by the courier-driver base when an operator overrode the per-carrier default. <code>AIEO_Courier_Driver_Base::tracking_url()<\/code> now consults the operator-saved template first\n* NEW: filter <code>aieo_custom_carriers<\/code> \u2014 themes \/ plugins can register carriers from <code>functions.php<\/code>, same pattern as WooCommerce Shipment Tracking's <code>wc_shipment_tracking_get_providers<\/code><\/p>\n\n<p><strong>Fulfillment \u2014 Settings<\/strong>\n* NEW: \"Backfill customer shipping paid\" card \u2014 one-shot retrospective pass that fills <code>_aieo_customer_shipping_paid<\/code> on historical orders so the Shipment Cost reports' income column is populated for past periods (not only orders placed after the cost-tracking went live)<\/p>\n\n<p><strong>Shipment Cost reports<\/strong>\n* NEW: sortable column headers on the results table \u2014 click to sort by orders \/ income \/ our cost \/ free-shipping subsidy. In-memory client-side sort (the result set is already paginated server-side)<\/p>\n\n<p><strong>Role-based pricing \u2014 CSV round-trip<\/strong>\n* Fixed: import now strips a leading UTF-8 BOM from the uploaded file before parsing (Excel-on-Windows exports leave one). Previously caused \"must include sku column\" errors when the actual header was <code>\\xEF\\xBB\\xBFsku<\/code>\n* Fixed: import auto-detects the separator (<code>,<\/code> vs <code>;<\/code> vs <code>\\t<\/code>) by counting candidates in the first line. Greek-locale Excel exports use <code>;<\/code>; the previous hardcoded <code>,<\/code> parser produced unparseable single-column rows\n* Improved: import error messages now state the detected separator and the header row that was parsed, so operators can see exactly why their file was rejected\n* Fixed: export no longer prepends a UTF-8 BOM. Cross-environment round-trips (export from one site, import into another) used to fail until the import learned to strip BOMs; now the file is BOM-clean from the start, keeping <code>cat<\/code> \/ <code>awk<\/code> \/ <code>diff<\/code> output untouched as well<\/p>\n\n<p><strong>Critical fix \u2014 Social Login settings silently wiped on every Save<\/strong>\n* Fixed: <code>AIEO_DMM_Social_Login::ajax_save_settings()<\/code> used the <code>sanitize_text_field( $array )<\/code> anti-pattern as the guard for both <code>providers<\/code> and <code>intents<\/code> POST arrays. <code>sanitize_text_field()<\/code> on an array returns <code>''<\/code> (empty string), so <code>is_array('')<\/code> was always false \u2014 every Save click silently wrote empty providers + every-intent-off, regardless of what the operator had ticked in the UI. Symptom: \"I've enabled Google + Facebook for login \/ checkout but the buttons never render anywhere.\" The guard is now <code>is_array($_POST['providers'])<\/code> directly; per-field sanitization (<code>sanitize_text_field<\/code>, <code>sanitize_key<\/code>) still runs on each value. Operators with previously-wiped settings need to re-enter their config once\n* Same anti-pattern was caught in 3 other modules in 5.2 (see memory <code>wp_sanitize_text_field_array_antipattern<\/code>); this one slipped through because the SSO admin tab is less frequently tested<\/p>\n\n<p><strong>Marketplace Order Importer \u2014 webhook setup guide + Rooster-derived tokens<\/strong>\n* NEW: per-vendor \"Setup help\" card on the AIEO MOI \u2192 Vendors tab. Surfaces the webhook URL prominently with a one-click Copy button and per-provider step-by-step instructions for where to paste it into the marketplace's merchant panel. For Skroutz: deep-links to the exact <code>merchants.skroutz.gr<\/code> settings page, names the field operators need to find (\"Webhook URL \/ Webhook \u03c0\u03b1\u03c1\u03b1\u03b3\u03b3\u03b5\u03bb\u03b9\u03ce\u03bd\"), and reminds them to deactivate the legacy <code>skroutz-marketplace-xml-for-woocommerce<\/code> plugin once the new URL is saved. Poll-only providers (Shopflix, eMag) get the card skipped \u2014 nothing for the operator to do\n* NEW: webhook tokens on freshly-created vendors are now derived from the operator's Rooster API key via <code>substr(hash('sha256', $rooster_key . '|moi-webhook|' . $vendor_slug), 0, 20)<\/code>. Each install gets a unique, stable, self-identifying webhook URL \u2014 and the URL is regenerable from the Rooster key alone, so losing the vendor row no longer means re-pasting random tokens into every marketplace panel. Hash, not substring, so the token never exposes any portion of the Rooster key. Falls back to a random token on standalone (non-Rooster) installs\n* NEW: per-vendor \"Use Rooster-derived token\" button on the setup card lets operators migrate existing random tokens to the Rooster-derived value (a small \"\u2713 Token derived from your Rooster API key\" badge then appears under the URL). Skips gracefully when Rooster isn't connected\n* <code>AIEO_MOI_Vendor_Manager::derive_webhook_token_from_rooster($slug)<\/code> + <code>rotate_webhook_token_from_rooster($id)<\/code> are the new helpers; new optional contract method <code>webhook_setup_steps($url)<\/code> on providers drives the per-provider guidance (Skroutz ships it; absent on poll-only providers)<\/p>\n\n<p><strong>Product Display \u2014 classic-theme info-column ordering<\/strong>\n* Fixed: the operator-saved Display Order for the info-column cluster (Product Meta \/ Payment Logos \/ Trust Badges \/ \u2026) was only being honored on FSE themes. On classic themes those modules were hardcoded to <code>woocommerce_single_product_summary<\/code> priorities 30 \/ 35 \/ 40, so Product Meta always rendered last regardless of how the operator dragged the rows. New <code>AIEO_DMM_Product_Display::reorder_classic_theme_cluster()<\/code> re-prioritises the three callbacks into the 31\u201334 band per the saved order, mirroring the existing <code>reorder_classic_theme_recos()<\/code> pattern. Modules with independent slot logic on classic themes (Brand Display's position picker, Brand Gifts' pre-cart band, Complementary \/ Waitlist \/ Product Needs' add-to-cart-form positions) are intentionally left where they are<\/p>\n\n<p><strong>Deprecation<\/strong>\n* <code>AIEO_DMM_Shipment_Tracking<\/code> module renamed in the admin sidebar to \"Shipment Tracking (legacy)\" with a yellow deprecation banner. The new Fulfillment \u2192 Carriers system supersedes it end-to-end; the legacy module will be removed in a future release<\/p>\n\n<h4>5.5 - 2026-05-23<\/h4>\n\n<p><strong>MAJOR RELEASE: WooCommerce 10.9 forward-compatibility + critical fix for the silent variation-attribute wipe + unified third-party variation gallery filter<\/strong><\/p>\n\n<p><strong>Critical fix \u2014 silent loss of variations on save (long-standing bug)<\/strong>\n* Fixed: products whose variation attribute is type <code>image<\/code> or <code>button<\/code> no longer lose their <code>is_variation<\/code> declaration when the parent product is saved. The bug: AIEO's <code>image<\/code> \/ <code>button<\/code> attribute types never registered an admin form-field renderer for their term multi-select. When WC's classic editor's product-save handler ran, <code>attribute_values[]<\/code> was empty in POST for those attribute rows, so WC's <code>WC_Meta_Box_Product_Data::prepare_attributes()<\/code> dropped them \u2014 wiping <code>_product_attributes<\/code> for the variation attribute on every product save\n* Fixed: new public method <code>AIEO_DMM_Swatches::render_custom_attribute_terms_select()<\/code> hooks <code>woocommerce_product_option_terms<\/code> for <code>color<\/code>\/<code>image<\/code>\/<code>button<\/code> types and emits the same <code>wc-taxonomy-term-search<\/code> multiselect WC uses for <code>select<\/code>-typed attributes. Future saves preserve <code>_product_attributes<\/code> correctly\n* Added: one-shot auto-repair for products that were already silently broken. On plugin update, reconstructs the missing variation-attribute declaration from each variation's <code>attribute_pa_*<\/code> postmeta and re-attaches the term relationships to the parent. Skips products that reference deleted (orphan) taxonomies \u2014 those need manual re-mapping by the operator<\/p>\n\n<p><strong>WooCommerce 10.9 forward-compatibility \u2014 <code>variation_gallery<\/code> + <code>wc-visual-attribute<\/code><\/strong>\n* NEW: declares compatibility with WC 10.9's experimental <code>variation_gallery<\/code> feature via <code>FeaturesUtil::declare_compatibility()<\/code>. When merchants enable the toggle in Settings \u2192 Advanced \u2192 Features, AIEO's variation gallery data is already in WC's canonical postmetas \u2014 no migration window, no broken stores\n* NEW: declares compatibility with WC 10.9's experimental <code>wc-visual-attribute<\/code> (Color swatches for attributes) feature\n* Schema migration: <code>botiga_variation_gallery<\/code> \u2192 <code>_thumbnail_id<\/code> + <code>_product_image_gallery<\/code> (CSV) + <code>_wc_variation_gallery_legacy_fallback_disabled = yes<\/code> sentinel on every variation. Video entries (uploaded video attachments + YouTube \/ Vimeo embed JSON) relocate to the AIEO sidecar <code>_aieo_variation_gallery_videos<\/code> with their original positions preserved for re-interleaving at render time\n* Schema migration: term swatch metas <code>product_attribute_color<\/code> \/ <code>product_attribute_color_type<\/code> \/ gradient + multiple sub-keys \u2192 WC canonical <code>color<\/code> term meta + AIEO sidecars (<code>_aieo_swatch_color_type<\/code>, <code>_aieo_swatch_gradient<\/code>, <code>_aieo_swatch_multiple<\/code>). Image-type swatches relocate <code>product_attribute_image<\/code> \u2192 <code>_aieo_swatch_image_id<\/code>. Legacy keys are preserved as read-fallback during the cutover window\n* Schema migration: attribute taxonomies with <code>attribute_type = 'color'<\/code> flip to <code>wc-visual<\/code> so WC's native chips, filter blocks, and the variation-selector inner block recognise them. Operator-opt-in: the flip only runs when WC's <code>wc-visual-attribute<\/code> feature is enabled\n* Migration runs via Action Scheduler in 250-item batches; idempotent; also exposed as <code>wp aieo migrate wc-compat<\/code> for manual \/ observable runs\n* When WC's <code>variation_gallery<\/code> feature is enabled, AIEO unhooks <code>\\Automattic\\WooCommerce\\Internal\\VariationGallery\\ClassicVariationGalleryAdmin::render_variation_gallery_field<\/code> so the admin shows AIEO's picker (which handles videos) instead of two competing pickers<\/p>\n\n<p><strong>New filter <code>aieo_variation_gallery_image_ids<\/code> \u2014 bridge for third-party storage<\/strong>\n* NEW: single public filter <code>apply_filters('aieo_variation_gallery_image_ids', $ids, $variation_id, $context)<\/code>. Third-party plugins \/ themes (Iconic Variations, the retired WooCommerce.com Additional Variation Images extension, custom themes) hook this filter from <code>functions.php<\/code> to tell AIEO where they store variation gallery image IDs. Return non-null array to short-circuit; return null to delegate to AIEO's canonical \u2192 legacy resolution\n* NEW: <code>AIEO_DMM_Variations_Gallery::resolve_image_ids($vid, $ctx)<\/code> \u2014 the single public reader every AIEO module calls. Replaces direct postmeta reads in: variation gallery admin picker, <code>woocommerce_available_variation<\/code> JS payload, <code>aieo\/product-variations-gallery<\/code> block render, exchanger import\/export, data-prep stage\n* <code>$context<\/code> values: <code>'admin'<\/code>, <code>'frontend'<\/code>, <code>'block_render'<\/code>, <code>'data_prep'<\/code>, <code>'serializer'<\/code> \u2014 let third-party adapters apply different rules per caller\n* Documentation: <code>docs\/FILTER_VARIATION_GALLERY_IMAGE_IDS.md<\/code> with 4 worked examples (Iconic, Additional Variation Images, custom theme, context-aware) + performance + testing notes<\/p>\n\n<p><strong>Marketplace feeds gain variation gallery URLs<\/strong>\n* NEW: <code>vitals.image_gallery_urls<\/code> (existing column, now populated) gets a fresh data-prep stage that walks <code>_product_image_gallery<\/code> for each row and emits a CSV of full-size URLs. Marketplace feeds (Google Shopping <code>g:additional_image_link<\/code>, Skroutz <code>&lt;additional_image&gt;<\/code>, Shopify <code>images<\/code>) now ship variation galleries without a separate API call\n* SQL bulk-fill (canonical <code>_product_image_gallery<\/code> first, legacy <code>botiga_variation_gallery<\/code> fallback) handles 20-image galleries via a chained <code>SUBSTRING_INDEX<\/code> walk; ~1s for 39k rows on the FF benchmarker\n* PHP post-pass applies the <code>aieo_variation_gallery_image_ids<\/code> filter only when registered, so the typical store pays zero extra DB cost<\/p>\n\n<p><strong>Cart, sticky-add-to-cart, and product-card readers updated for the new sidecar metas<\/strong>\n* <code>class-aieo-dmm-swatches-runtime.php::resolve_term_color_style()<\/code> \u2014 read order is now AIEO sidecar (<code>_aieo_swatch_color_type<\/code> + <code>_aieo_swatch_gradient<\/code> \/ <code>_aieo_swatch_multiple<\/code>) \u2192 WC canonical <code>color<\/code> \u2192 legacy <code>product_attribute_color*<\/code>. Gradient and multiple-color swatches keep rendering as before; new term edits use canonical + sidecar without breaking legacy plugins that still read the old keys\n* <code>class-aieo-dmm-swatches-runtime.php::resolve_term_image_src()<\/code> \u2014 <code>_aieo_swatch_image_id<\/code> \u2192 <code>product_attribute_image<\/code> \u2192 new <code>aieo_swatch_image_id_for_term<\/code> filter for forward-compat when WC adds image swatches (currently WC10.9-dev ships color swatches only)\n* <code>class-aieo-dmm-checkout-product-images.php<\/code> \u2014 same sidecar \u2192 canonical \u2192 legacy chain when picking the cart-line variation thumbnail\n* <code>class-aieo-dmm-sticky-atc.php<\/code> \u2014 color, gradient, multiple-color, and image swatches all read through the new resolution chain. Sticky cart on PDP keeps rendering brand-specific image swatches identically pre- and post-migration\n* <code>class-aieo-dmm-data-prep-scheduler.php<\/code> \u2014 SQL for <code>variation_swatch<\/code> and <code>image_url<\/code> updated to two-pass (canonical preferred, legacy as <code>WHERE NULL<\/code> fill-in)<\/p>\n\n<p><strong>Custom carriers \u2014 inline Edit + new third-party filter<\/strong>\n* NEW: inline Edit button on every row in the \"Carriers without API\" admin table. Label and tracking-URL template become editable in place; Save \/ Cancel pair posts to the same <code>aieo_ff_save_custom_carrier<\/code> AJAX endpoint (slug is the upsert key). The shipping-method-link dropdown keeps its own per-row autosave \u2014 Edit doesn't touch it\n* NEW: filter <code>aieo_custom_carriers<\/code> lets themes \/ plugins register carriers from <code>functions.php<\/code>, mirroring WooCommerce Shipment Tracking's <code>wc_shipment_tracking_get_providers<\/code> pattern. Carriers added via filter appear identically to operator-added ones in the admin table, the order-row tracking dropdown, and customer emails. Operator overrides via save win on the next read (option-side wins because the upsert is final)<\/p>\n\n<p><strong>Exchanger (product import\/export) writes WC canonical<\/strong>\n* <code>class-aieo-exchanger-product-serializer.php<\/code> \u2014 variation gallery export goes through <code>resolve_image_ids()<\/code>, so third-party filters and WC10.9 canonical reads both round-trip correctly\n* <code>class-aieo-exchanger-product-importer.php<\/code> \u2014 imported variation galleries now write to <code>_thumbnail_id<\/code> + <code>_product_image_gallery<\/code> + sentinel (drops the legacy <code>botiga_variation_gallery<\/code> write target). Existing exports stay readable<\/p>\n\n<p><strong>Attribute-type registration cleanup<\/strong>\n* <code>available_attribute_types()<\/code> \u2014 keeps AIEO-only <code>image<\/code> + <code>button<\/code> types always. Registers <code>color<\/code> only when WC's <code>wc-visual<\/code> substitute isn't already present in the filter chain (avoids two \"Color\" entries in the admin dropdown post-migration). Pre-migration \/ WC feature off, behavior is unchanged<\/p>\n\n<p><strong>Tested up to: WooCommerce 10.9-dev nightly, validated on the femme-fatale.gr benchmarker (39k vitals rows, 7,443 variations migrated, 6,789 with multi-image galleries). Legacy <code>om-product-swatches<\/code> v1.0.4 coexists cleanly \u2014 both plugins write their own keys on term save, no conflict<\/strong><\/p>\n\n<h4>5.0 - 2026-05-15<\/h4>\n\n<p><strong>MAJOR RELEASE: Insights Chat (Claude-powered), Joint Session \u00d7 Attribution Analytics, Four-Layer Retention, and the Pro Tier<\/strong><\/p>\n\n<p><strong>Insights Chat \u2014 Claude-powered, in-admin<\/strong>\n* NEW: Tools \u2192 Insights Chat \u2014 ask your shop questions in plain language using the AI Chat Anthropic key you already have\n* NEW: 33 purpose-built Claude data abilities (registered through the WordPress Abilities API)\n* NEW: Categorized accordion suggestion chips across 11 question groups \u2014 Customers, Brand portfolio, Recommendation rails, Attribution &amp; archives, Product needs audit, Star ratings, Content &amp; blog, Cross-skill, Store analytics, Promotions \/ launches \/ sales, Newsletters &amp; campaigns\n* NEW: Tool-use loop with bidirectional Anthropic-safe tool naming\n* NEW: All chips and abilities respect manage_woocommerce capability<\/p>\n\n<p><strong>Session Tracker \u00d7 Attribution Engine Integration<\/strong>\n* NEW: Cross-cuts engagement (session tracker) with conversion (attribution engine) via a shared aieo_session_id cookie\n* NEW: Blog-post attribution \u2014 clicks from blog posts to products now carry source=blog_post + source_meta.post_id\n* NEW: Engagement-bucket buy-probability \u2014 empirical P(cart-add) per (scroll-quartile, time-quartile, mouse-activity) bucket\n* NEW: Abandoned-cart triage, cart-removal analysis, rating \u00d7 conversion correlation, need \u00d7 conversion correlation\n* NEW: 11 new joint-analytics abilities backing the chat suggestion chips\n* Improved: Attribution Engine now respects Session Tracker's consent state (GDPR alignment)<\/p>\n\n<p><strong>Insights Remote DB Streaming + Four-Layer Retention<\/strong>\n* NEW: Insights Remote DB Settings tab \u2014 stream raw events to your own operator-owned MariaDB \/ MySQL via the existing ERP connection registry\n* NEW: Configurable export frequency (15 min \/ hourly \/ daily) with per-table lag dashboard and dry-run \"Test export\"\n* NEW: 5 pre-aggregated daily rollup tables so the chat abilities never hit raw event tables \u2014 millisecond responses regardless of history size\n* NEW: aieo_aggregate_rollups nightly cron + unified aieo_archive_run weekly cron\n* NEW: Tightened hot retention \u2014 14 days (sessions), 30 days (reco events), 365 days (cart-adds)\n* NEW: Local-purge failsafe \u2014 hot rows are NOT deleted until the remote-export bookkeeping confirms receipt\n* Improved: Net stable DB footprint ~1.1 GB year-over-year (was unbounded \u2014 projected 6-8 GB by year 2)<\/p>\n\n<p><strong>Star Ratings \u2192 SEO Schema Bridge<\/strong>\n* NEW: AggregateRating JSON-LD bridged into AIOSEO, Yoast, and RankMath via their schema filters\n* NEW: Fallback head-injected JSON-LD when no SEO plugin is detected\n* NEW: Per-feature enable\/disable toggle on the Star Ratings admin page<\/p>\n\n<p><strong>Floating Mini Side-Cart, Sticky ATC &amp; Free-Shipping Bar<\/strong>\n* NEW: Two-column floating mini-cart \u2014 left: \"You might like\" recommendations, right: Shopping Bag \/ Recently Viewed tabs with the free-shipping progress bar right under the tab header\n* NEW: 500 ms debounced quantity AJAX \u2192 400-byte JSON \u2192 optimistic client-side recompute \u2014 qty changes feel instant, no full cart recalculation on the server\n* NEW: Session-level HTML cache keyed by cart_hash (30 s TTL); WC fragments integration keeps every other widget in sync\n* NEW: Side-cart recommendations sourced from the DMM product-bundle endpoint \u2014 same cached HTML powers the product page AND the mini-cart\n* NEW: Sticky Add-to-Cart bar (DOM classes + JS global kept verbatim so existing CSS\/JS bundles work without modification)\n* NEW: Free-Shipping admin \u2014 threshold + product \/ brand exclusions, with the package-rates filter that strips free shipping when any excluded item is in the cart<\/p>\n\n<p><strong>Pricing Engine \u2014 Role Pricing, Brand Discounts, Loyalty Classes<\/strong>\n* NEW: Per-role price overrides via CSV upload (staged batch validation \u2192 AJAX batches); mirrors into the legacy om-role-pricing table so existing storefront integrations keep working byte-for-byte\n* NEW: Brand-level % discounts with optional start\/end-date windows\n* NEW: Loyalty class definitions + user assignments \u2014 applied in the global pricing recipe by AIEO_DMM_Pricing_Engine\n* NEW: Stacking recipe: Role Pricing \u2192 Brand Discount \u2192 Loyalty Class \u2014 each customer sees the strongest applicable price<\/p>\n\n<p><strong>Conversion Boosters \u2014 Brand Gifts &amp; Exit Intent<\/strong>\n* NEW: Brand-based free-gift offers \u2014 gift (price = 0) auto-added when the cart subtotal of the offer's brand(s) crosses min_subtotal within the date window\n* NEW: Configurable exit-intent modal \u2014 fires on cursor exit-intent after a warm-up delay; two HTML bodies (generic site-wide + upgraded checkout-specific); optional restriction to checkout-only or anonymous visitors; session-storage dismissal\n* NEW: Legacy <code>exit-intent-offer<\/code> standalone plugin auto-imported on first read and deactivated \u2014 no manual migration<\/p>\n\n<p><strong>Marketplace Connectors &amp; Shipping<\/strong>\n* NEW: Marketplace Order Importer \u2014 pulls Skroutz \/ e-shop \/ Amazon orders into WooCommerce as native orders so attribution, stock, customer profiles, and fulfillment stay unified. Per-vendor webhook URLs with rotatable tokens, configurable SKU strategy, default order status per vendor\n* NEW: Streaming Marketplace Feeds generator \u2014 handles 35k-product catalogues without blowing memory; include\/exclude rules by product or brand, XML or CSV output, per-feed cron registration on save\n* NEW: Shipment Tracking provider list cleaned up \u2014 drops US\/UK\/Canada\/Germany defaults, adds Greek + Cypriot carriers + Stoferno.gr\n* NEW: Smart Shipping Label \u2014 guests \/ postcode-less carts see \"Carrier (\u0391\u03c0\u03cc \u20acX.XX)\" with the minimum rate so they know shipping isn't free without seeing a misleading default. Free-shipping carts hide method prices and the generic \"Free shipping\" pseudo-method (customer still picks a real carrier, just with \u20ac0). Greek \"184 53\" postcodes auto-normalize to \"18453\"<\/p>\n\n<p><strong>Customer Intelligence + Web Push + Voice-of-Customer<\/strong>\n* NEW: wp_aieo_customer_intelligence \u2014 keyed by eponymous_id (AIEO's canonical customer identity), with secondary wp_user_id + source_table columns so anonymous \u2192 logged-in stitching has a single home\n* NEW: Chunked recompute stored procedure over AIEO's pre-built snapshot tables \u2014 omnichannel customer view (eshop + in-store merged) is the source of truth\n* NEW: Behavioural segments \u2014 Top customers, Lost cohort, Lookalikes, Abandoned-cart, reactivation\n* NEW: Triggered web-push flows \u2014 welcome, reactivation, price-drop, back-in-stock \u2014 with full dispatch log + per-subscriber delivery + click attribution\n* NEW: Customer Survey Intelligence \u2014 Gravity Forms 18 + 20 ingest (real-time hook + daily cron safety net + manual button), 7 high-signal metrics (NPS class, overall satisfaction, professional-verified, personal priorities, discovery channel, gift category preference, personal profile), composite voc_score (0-100)\n* NEW: \"Notify me when back in stock\" Waitlist \u2014 out-of-stock product pages render the signup form, stock watcher emails subscribers when stock flips back; one-shot migration from the legacy PPE waitlist table\n* NEW: Wishlist analytics \u2014 read-only admin views: which products are most-wishlisted, which surfaces drive adds, which pages \/ categories convert to wishlist<\/p>\n\n<p><strong>Pro Tier \u2014 Frosted-Glass Overlays on 13 Admin Tabs<\/strong>\n* NEW: Apple-glass overlay with PRO badge, feature-specific title + description + bullets, and \"Upgrade to Pro\" CTA\n* NEW: Pro-locked tabs \u2014 Attribution Dashboard, Advertising Campaigns, Web Push, Customer Intelligence Surveys, Insights Chat, Shipment Cost Reports, Insights Remote DB Settings, Action Scheduler Cleanup, ERP Bridge, ERP Database, Order Documents &amp; Couriers, Marketplace Order Importer, Branch Stock Scanner, Order Cancellations\n* Improved: Pro detection now honors BOTH paths \u2014 eshop-optimizer.com Pro membership OR a valid rooster.systems Content Connector API key (either is sufficient)\n* Improved: Locked tabs do not execute heavy queries or expose credentials for non-Pro operators<\/p>\n\n<p><strong>Attribution Menu Restructure<\/strong>\n* NEW: New top-level \"Attribution\" menu group containing the Dashboard and the Advertising Campaigns admin\n* NEW: Campaigns auto-populate from utm_campaign \u2014 no manual correlation needed; new campaign slugs appear as auto_draft rows after the next dashboard load\n* Improved: Advertising Campaigns moved from Pricing &amp; Offers into Attribution (same dropdown as the dashboard it shares data with)<\/p>\n\n<p><strong>Greek Translation Pass + i18n Hygiene<\/strong>\n* NEW: ~70 new Greek (el) translation strings covering Pro overlays, suggestion chips, and admin navigator labels\n* Improved: All 11 admin-navigator group labels wrapped in __()\n* Improved: 117 i18n errors fixed across the plugin<\/p>\n\n<p><strong>Plugin-check &amp; Security Hygiene<\/strong>\n* Improved: Plugin-check ERRORs reduced from 132 to 0 (excluding the agreed-upon DB stored-procedure exceptions acknowledged by the WordPress.org plugin review team)\n* Improved: All AJAX handlers routed through a centralised nonce verifier\n* Improved: Every new DB-touching ability has min\/max input bounds and sanitize_key on all string keys<\/p>\n\n<p><strong>Architectural Improvements<\/strong>\n* NEW: Module V2 manifest pattern (data\/admin\/frontend\/compute split scaffolding \u2014 opt-in per module migration)\n* NEW: .distignore file at plugin root keeps internal docs, dev tooling, and the Claude Code skill pack out of the wp.org distribution  &hellip;<\/p>","raw_excerpt":"Adaptive productivity, conversion &amp; retention for eshops and content sites. Anthropic\/Voyage AI: messaging, recommendations, attribution, loyalty, &hellip;","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ur.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/192766","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ur.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/ur.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/ur.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=192766"}],"author":[{"embeddable":true,"href":"https:\/\/ur.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/oxfordmetadata"}],"wp:attachment":[{"href":"https:\/\/ur.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=192766"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/ur.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=192766"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/ur.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=192766"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/ur.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=192766"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/ur.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=192766"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/ur.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=192766"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}