feat: implement WooCommerce AJAX product search

This commit is contained in:
XShop
2026-09-13 20:01:15 +03:30
parent 00439fcea9
commit f5c283af25
14 changed files with 760 additions and 37 deletions
+15 -23
View File
@@ -15,33 +15,24 @@ Two installable artifacts: theme (`xshop`) + plugin (`xshop-core`). Theme never
## 2. Theme – `xshop-theme`
### 2.1 File map (M2)
### 2.1 File map (M3)
```
xshop-theme/
style.css
functions.php # thin loader
screenshot.png / rtl.css
header.php / footer.php / index.php / front-page.php / single.php / page.php / archive.php / search.php / 404.php / sidebar.php / comments.php
style.css / functions.php / rtl.css / header.php / footer.php / index.php etc
inc/
setup/ # theme-support, menus, sidebars, body-classes, assets (woo.css global, documented)
helpers/ # sanitize, template (xshop_has_woocommerce etc)
customization/ # options
compatibility/ # gutenberg, elementor
woocommerce/ # wrappers, loop_start/end, toolbar, remove gallery, related args, product.js enqueue, cart quantity filter
performance/ # defer
setup/assets.php — tokens→base→layout→components→woo→utilities→style.css + theme.js + search.js (front-end only where data-xshop-search exists, documented)
woocommerce/setup.php — loop_start/end, toolbar, gallery remove, related 4/4, product.js conditional
assets/
css/ # tokens, base, layout, components, woo (shop/product/cart/account/checkout), utilities
js/ # theme.js + product.js (gallery thumbs, keyboard)
css/woo.css — + search dropdown (.xshop-search, _dropdown, _results, _item, responsive fixed @640)
js/search.js — debounce 250ms, AbortController, stale seq, keyboard, a11y
template-parts/components/
site-header/-footer, breadcrumbs, pagination, search-form, post-card,
product-card.php (WC_Product, badges, price, rating, hooks), product-grid.php, product-gallery.php (featured+thumbs, keyboard), mini-cart.php, empty-state, loading, section-heading, hero, promo-banner
woocommerce/
content-product.php (3.6.0) — delegates to product-card
archive-product.php (3.4.0) — shop/category header + toolbar + grid + empty-state CTA
content-single-product.php (3.6.0) — grid gallery+summary, hooks preserved
single-product.php (1.6.4) — delegator to content-single-product
languages/
ajax-search.php — reusable combobox (role=combobox, aria-expanded/controls, listbox, live status)
+ previous M2 components
woocommerce/ — 4 overrides as M2
xshop-core/
includes/REST/Search.php — xshop/v1/search endpoint
includes/Core/Plugin.php — loads REST/Search.php
```
### 2.2 Bootstrap
@@ -116,9 +107,10 @@ Tokens: `tokens.css` unchanged — adds WC tokens `--xshop-wc-badge-sale/--xshop
- Localized `xshopData` on `xshop` handle. No jQuery for theme code; Woo's jQuery remains for variations/add-to-cart.
- Build: `tools/build-release.ps1` now includes top-level folder `xshop/` wrapper (fixed in M1.1).
## 7. AJAX / REST
## 7. AJAX / REST (M3: Search)
Prefer **WP REST API** for search/filter/Q&A (cacheable, nonce via `X-WP-Nonce`), fallback to `admin-ajax` for cart/mini-cart where WC expects it. All endpoints: sanitize → validate → capability check → nonce → escaped output.
- **Search**: `GET /wp-json/xshop/v1/search?search=&limit=` via `xshop-core/includes/REST/Search.php:1` (`register_rest_route xshop/v1/search`). Public read-only (`permission_callback __return_true`), sanitized `search` (trim/strip_tags/sanitize_text_field/max 100) + `limit` 1..20, min length 2 returns empty without DB, `WP_Query` s + `_sku` LIKE, `post_status publish`, `no_found_rows`, `fields ids` deduped to `limit` (default 6), response `{items:[{id,title,url,image,price_html,type,in_stock}], total}` + `Cache-Control: public, max-age=60`. No private data, no N+1, no draft, no customer/order, `wc_get_product` only for returned IDs.
- Prefer REST for search/filter/Q&A, fallback `admin-ajax` for cart where WC expects.
## 8. Security Model