=== Hostious AJAX Search for WooCommerce ===
Contributors: hostiousio
Tags: woocommerce, product search, ajax search, live search, search
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 3.2.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Fast live product search for WooCommerce with its own search index, typo tolerance, synonyms, search analytics and Danish word forms.

== Description ==

Hostious AJAX Search shows matching products, categories, tags, brands, posts and pages while your customers type. Search runs on the plugin's own index, so suggestions typically arrive in a few milliseconds even in large catalogues.

= Features =

* Live suggestions with product image, price, SKU, description, sale and featured badges.
* Own search index with automatic updates when products, variations, categories or tags change.
* Typo tolerance (fuzzy search), synonyms and search in SKU, GTIN/EAN, attributes, categories, tags, brands and custom fields.
* Danish word forms: "skovle" finds "skovl", and "roerboejle" finds "rørbøjle".
* Variations as separate results or matched by their SKU.
* Details panel with add to cart, search history and full-screen search on mobile.
* Search results page powered by the same index.
* Search analytics: what customers search for, which searches find nothing, one-click synonyms and an optional weekly e-mail report.
* Search bar as shortcode, block, widget, menu item, Elementor widget and Breakdance element, plus ready-made integrations for many themes.
* Integrations with FlyingPress and WP Rocket, WPML, Polylang, TranslatePress, B2B and membership plugins, product filters and more.
* Danish and English interface. The plugin language can follow the site language.
* No license key, no account, no upsells. All features are included.

== Installation ==

1. Install and activate WooCommerce.
2. Install Hostious AJAX Search from Plugins → Add New, or upload the ZIP file, and activate it.
3. Open WooCommerce → AJAX Search. The search index is built automatically; follow the progress under Indexing.
4. Add the search bar with the shortcode `[hostious_search]`, the "Hostious.io" block, the Breakdance element "Hostious Search", a widget or a menu item.

== Frequently Asked Questions ==

= How do I add the search bar? =

Use the shortcode `[hostious_search]` (for example `[hostious_search layout="icon"]`), the "Hostious.io" block, the widget, a menu item under Appearance → Menus, the Elementor widget or the Breakdance element "Hostious Search". For posts and pages there is also `[hostious_search_posts_results]`.

= Which layouts and styles are available? =

Layouts: search bar, search icon, icon on mobile and bar on desktop, or the reverse. Styles: Solaris (square) and Pirx (rounded). The mobile breakpoint, colours, the submit button and a darkened background while searching can be set under Search bar.

= How does typo tolerance work? =

When a word is not found, the index looks for words within two letters of what was typed, starting with the same two letters. "minigravr" finds "minigraver".

= How do synonyms work? =

Under Search content → Synonyms, write words that should find the same products on one line, separated by commas, for example `sofa, couch, settee`. In Search analytics you can add a search that found nothing as a synonym with one click. The index is rebuilt after changes.

= What are Danish word forms? =

With Danish word forms switched on (default on Danish sites), plural and definite forms share a stem, so "skovle", "skovlen" and "skovlene" find "skovl", and "ae", "oe" and "aa" are read as "æ", "ø" and "å". SKUs and codes are not changed.

= Can I exclude or include products? =

Yes. Under Search content → Exclude/include products you can leave out, or search only in, products from chosen categories, tags or attributes.

= What is the details panel? =

An optional panel next to the suggestions that shows a larger image, price, stock and an add to cart button for the product the cursor is on.

= What is the search history? =

When a customer clicks the empty search field, the latest searched phrases and viewed products are shown. It is stored in the customer's browser only.

= Can customers search by SKU, GTIN or EAN? =

Yes. Searching in SKU is on by default for new installations, and GTIN/EAN search appears when your products have those values.

= How does the index stay up to date? =

Product, variation and term changes are queued and indexed in the background. A full rebuild can be scheduled under Indexing, run from the settings or with WP-CLI: `wp hostious-search index build`.

= Can the "No results" message contain HTML? =

Yes. The tags h1-h6, p, ul, ol, li, b, em, br, div, span and a are allowed, so you can link to your contact page or popular categories.

= What does the mobile overlay do? =

On small screens the search opens in full screen, which makes typing and reading suggestions easier.

= Can I search in custom fields? =

Yes. Under Search content you can add product custom fields (meta keys) to the index.

= What does search analytics record? =

The phrases customers searched for, the number of results and the date. Typing a word counts as one search, not one per keystroke. Searches from crawlers and bots and test searches from the admin are ignored. No IP addresses or user data are stored; to join the keystrokes of one search, an anonymous hash is kept for 90 seconds. Records older than 30 days are removed automatically.

= Does it work with FlyingPress and WP Rocket? =

Yes. The search scripts are excluded from "Delay JavaScript" when it waits for user interaction, the suggestion styles are kept by "Remove unused CSS", and FlyingPress' page cache is cleared when you change settings that affect the search bar.

= I used the previous Hostious edition in the folder ajax-search-for-woocommerce-premium =

Back up the site and deactivate the previous edition yourself, then install and activate this plugin. Version 3.2.0 recognizes previous Hostious settings, copies preferences and analytics into its own storage, adapts old widgets and saved search content, and builds its own index. Original data is retained. No other plugin is disabled automatically. Data belonging to an unrelated FiboSearch installation is not imported automatically. See README.md for custom-code migration requirements.

= Does the search respect B2B, membership and private store rules? =

Yes. With WooCommerce B2B, B2BKing, Addify B2B, MemberPress, WooCommerce Memberships, Protected Categories, Private Store, Catalog Visibility Options, Product Visibility by User Role, Wholesale Prices or Booster, the rules are evaluated for the current visitor in every search request. Hidden products and categories are left out of suggestions, the details panel and prices. The plugin does not start PHP sessions.

= I use shortcodes from an earlier edition =

Recognized Hostious upgrades keep older shortcodes working when no separate original search engine is active. New installations use `[hostious_search]` and `[hostious_search_posts_results]`. The filter `hostious/ajax_search/legacy_shortcodes` can disable the upgrade adapters; it does not enable foreign registrations on fresh installations.

= Is data deleted when I delete the plugin? =

No. Settings, the index and statistics are kept. To remove everything, add `define( 'HOSTIOUS_AJAX_SEARCH_DELETE_DATA', true );` to wp-config.php before deleting the plugin.

= Does the plugin contact external services? =

No. The plugin only sends requests to your own site, to build the index in the background. The optional weekly report is sent with your site's own e-mail.

== Screenshots ==

1. Search suggestions with categories, products, prices and the details panel.
2. Settings overview with quick settings and a search test.
3. Search analytics: searches that found nothing, with one-click synonyms.
4. The Hostious Search element in the Breakdance editor.

== Changelog ==

= 3.2.0 - 2026-10-22 =
* Prepared by Hostious.io for review. WordPress.org approval is not implied.
* Independent Hostious names for settings, tables, hooks, AJAX actions, scripts, styles, globals, blocks and Elementor widgets. Removed global class/function/namespace aliases for the original engine.
* Non-destructive migration of recognized earlier Hostious installations: preferences, analytics, sidebar widgets, saved blocks, Elementor widgets and menu search fields. Original data remains available for rollback; the new index is rebuilt.
* Removed bundled Vue 2, Selectize, Vue Selectize, Popper 1 and Tooltip 1. Admin fields use native controls enhanced by WooCommerce's installed SelectWoo; tooltips use WordPress jQuery UI.
* The locally maintained Settings API helper rejects unknown new request fields and preserves existing extension settings unchanged.
* Includes the private-store ID-search and secure loopback fixes from 3.1.1. No automatic deactivation of other plugins.
* Custom PHP hooks/constants and theme CSS/templates require migration to the new Hostious API; see README.md. Legacy shortcode/content adapters are restricted to recognized upgrades.

= 3.1.1 - 2026-10-22 =
* Security: a locked private store now blocks products and terms before all result formats, including ID-only search and direct lookups.
* Security: Basic-auth loopbacks require a trusted HTTPS origin, verified TLS and no redirects. Filtered diagnostics endpoints use the same safeguards.
* Activation no longer disables another plugin automatically. An administrator must resolve conflicting search engines using the plugin list.
* Corrected submission status and source-code documentation. Published by Hostious.io.

= 3.1.0 - 2026-10-22 =
* Security: every admin and AJAX action that changes data checks a nonce and the user's capability. Input on the diagnostics page and in integrations is validated, unslashed and sanitized; output is escaped when printed.
* Security: products and categories hidden by B2B, membership, private store and catalog visibility plugins stay hidden for the current visitor in suggestions, the details panel, dynamic prices and the fallback search.
* No PHP sessions: the visitor rules of WooCommerce B2B, MemberPress, Protected Categories, Private Store, Memberships and Booster are evaluated during the search request instead of being stored in a session on every page view.
* Search endpoint: answered after WordPress has fully loaded when such a plugin is active; the fallback search runs in the same request without an HTTP loopback; phrase and language are validated.
* JSON responses use wp_send_json() and wp_json_encode().
* All CSS and JavaScript is loaded through registered handles with wp_add_inline_style() and wp_add_inline_script(); admin assets are enqueued on admin_enqueue_scripts.
* Unique names: shortcodes [hostious_search] and [hostious_search_posts_results]; older shortcode names are kept only on sites updated from an earlier version (filter hostious/ajax_search/legacy_shortcodes). Background processes are renamed to hostious_search_*. Theme search shortcodes are replaced without registering generic shortcode names.
* Basic auth for loopback requests: credentials are passed on unchanged, validated and only sent to the site's own URLs. New constants HOSTIOUS_AJAX_SEARCH_BA_USERNAME and HOSTIOUS_AJAX_SEARCH_BA_PASSWORD.
* Libraries: Selectize 0.15.2 (was 0.12.6), Vue 2.7.16 (was 2.6.12), Popper.js 1.16.1 and Tooltip.js 1.3.3. The minified vue2-selectize bundle is replaced by a small readable component.
* Removed: leftover build markers and labels of the earlier edition, the promo settings box and an unused error-report path.
* Fixed: an output buffer left open by the search debugger, the dashboard widget script loading on every admin page, and the language and tokenizer fields on the diagnostics page.
* Compatible with PHP 8.5. Tested with WordPress 7.1 and WooCommerce 11.2.

= 3.0.0 - 2026-09-23 =
* Prepared for WordPress.org submission as Hostious AJAX Search for WooCommerce (slug hostious-ajax-search-for-woocommerce). WordPress.org updates become available after approval and publication; the self-hosted update handling and local plugin details were removed.
* The previous Hostious edition (folder ajax-search-for-woocommerce-premium) is switched off automatically on activation. Settings, search index and statistics are reused, FlyingPress' page cache is cleared and a one-time notice is shown.
* New search endpoint that answers on plugins_loaded, before the theme loads, without loading WordPress files directly. The alternative wc-ajax endpoint is still available.
* New: Danish word forms. "ae", "oe" and "aa" match "æ", "ø" and "å", and plural and definite forms share a stem (Snowball), so "skovle" finds "skovl" and "roerboejle" finds "rørbøjle". SKUs and codes are not changed. On by default on Danish sites.
* New: FlyingPress integration. Search scripts are excluded from "Delay JavaScript", the suggestion styles are kept by "Remove unused CSS", and the page cache is purged when search bar or suggestion settings change.
* New: add a search without results as a synonym with one click in Search analytics.
* New: optional weekly search report by e-mail (Mondays 07:00 site time) with searches, share with results, top phrases and searches without results.
* New: Breakdance and Oxygen element "Hostious Search".
* New: the plugin language can follow the site language (default), including WPML, Polylang and TranslatePress. Other languages use WordPress language packs.
* Searching in SKU is on by default for new installations.
* Search analytics: one entry per typed search instead of one per keystroke; crawlers, bots, result pages opened without a referrer from the site and admin test searches are ignored; Æ, Ø and Å are stored correctly and long phrases are cut without splitting a character.
* Fixed: the index was not rebuilt automatically after the plugin was updated.
* Fixed: help links pointed to a generic homepage; they now point to the FAQ and the Hostious contact page.
* Fixed: the weekly report and maintenance tasks failed when run from cron or WP-CLI.
* Fixed: the language filter ran twice for every default label.
* Fixed: suggestions and prices were underlined on sites that underline links, such as Breakdance and block themes.
* Security: request input is sanitized and unslashed, output is escaped, and translator comments were added to all strings with placeholders.
* Admin: new vector logo directly in the header without a dark box, sale prices shown correctly in the search test, critical searches in full width, Hostious green checkboxes on WordPress 7, compact header on mobile and spacing between checkboxes and their descriptions.
* Code: PSR-4 autoloader replaces the class map, the autoload bridge and per-file boilerplate; plugin integrations are loaded only when the plugin they support is active; unused code removed (legacy settings forms, an unused front-end scaffold, duplicate Vue build, failure-report e-mail preview).
* Minified files are built from the included sources (npm run build). Translation catalogs renamed to the new text domain.
* The change log is shown on the About page of the settings (Danish CHANGELOG.md or this change log) and linked from the plugin list. README.md (developer notes) and THIRD-PARTY-NOTICES.txt are included.

= 2.1.1 - 2026-09-22 =
* Original Hostious.io logo in the admin and on the troubleshooting page.
* One named lifecycle handler for the preview; the typing animation is length-based, stops when the preview is hidden or motion is reduced, and only touches the preview.
* Block editor translations are loaded only when a search block is registered, and only once per script handle.

= 2.1.0 - 2026-09-22 =
* New admin workspace: side menu with Overview, Search bar, Suggestions, Search content, Indexing, Search analytics, Setup & integrations, Troubleshooting, Tools & help and About, plus one fixed save button.
* Overview with index status, last completed build, saved key settings and four quick settings (image, price, description, SKU).
* Danish/English switcher in the header.
* Search test on Overview that calls the real search endpoint with the saved settings, with debounce, cancellation, timeout and clear error messages.
* All settings in one form with one nonce; old panel IDs and hash links keep working; warning on unsaved changes.
* Design preview beside the form on wide screens and below it on narrow screens.
* Fixed: reference to an undefined variable when focusing the placeholder field.
* Responsive layout with keyboard focus, ARIA states and reduced motion support.

= 2.0.2 - 2026-09-22 =
* Hostious wordmark and green colour palette in the admin.
* Cleaner settings header, tabs, cards and preview.

= 2.0.1 - 2026-09-22 =
* Fixed: fatal error (class not found) while updating from a ZIP file.
* Faster index updates: attachments, revisions and other non-product types are skipped early, and product objects are reused.
* Fixed: permanently deleted products, posts and pages are removed from the index.
* Fixed: deleting one variation no longer removes the parent product from search results.
* The WooCommerce menu item is called "AJAX Search"; "Contact support" link added.

= 2.0 - 2026-09-22 =
* All premium search features are available without a license key; license SDK, account activation, upsells and external update and error-report services were removed.
* New PHP namespace Hostious\AjaxSearch, accessor HOSTIOUS_AJAX_SEARCH(), shortcodes [hostious_search] and [hostious_search_posts_results] and theme template folder hostious-search/. Existing settings, tables, hooks, shortcodes, blocks and Elementor widgets are kept for compatibility.
* Danish and English interface with a plugin language setting.
* Fixed: a number field wrote its max value as a second min attribute, and a missing closing link tag in the synonym help.
* Uninstalling keeps settings, index and statistics unless HOSTIOUS_AJAX_SEARCH_DELETE_DATA is defined.

The full Danish change log with details is in CHANGELOG.md.

== Upgrade Notice ==

= 3.2.0 =
Back up first and test on staging. This version uses independent names and storage. Earlier Hostious data is retained and migrated, but custom PHP hooks/constants and theme CSS/templates must be updated to the new Hostious API. Deactivate any previous search engine manually.

= 3.1.1 =
Fixes private-store ID search and secures Basic-auth loopbacks. Administrators must deactivate a conflicting legacy search engine themselves; no other plugin is disabled automatically.

= 3.1.0 =
Security and compatibility update: no PHP sessions, stricter checks for admin actions and B2B/membership visibility, CSS and JavaScript loaded the WordPress way, PHP 8.5 support.

= 3.0.0 =
New plugin folder for WordPress.org. Activating it switches off the previous Hostious edition; settings, index and statistics are kept.

== Source code and libraries ==

The plugin's own human-readable sources are included: assets/js/search.js, assets/js/admin.js, the CSS files in assets/css and the block sources in src/blocks. package.json provides the build commands (terser, clean-css and @wordpress/scripts). See README.md. Bundled third-party libraries retain their notices; upstream sources are linked below. WordPress jQuery UI and WooCommerce SelectWoo are runtime dependencies supplied by those installed plugins, not bundled copies.

Bundled libraries:

* Ajax Autocomplete for jQuery (Devbridge), MIT, https://github.com/devbridge/jQuery-Autocomplete, modified
* classnames 2.5.1, MIT, https://github.com/JedWatson/classnames; full notice in THIRD-PARTY-NOTICES.txt
* WordPress Settings API class by Tareq Hasan (weDevs), GPL
* Search engine support classes based on TNTSearch, MIT, https://github.com/teamtnt/tntsearch
* Danish stemmer implemented from the Snowball algorithm, BSD 3-Clause, https://snowballstem.org/

See THIRD-PARTY-NOTICES.txt for details.
