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
+42
View File
@@ -165,3 +165,45 @@ Same XAMPP WP 7.1 / WC 11.1.0 / PHP 8.2.12, with additional products:
## Conclusion
**M2 ACCEPTED** — Shop/category/grid/card/sorting/pagination/empty, product gallery + variable with real variations (price/stock reset/add-to-cart), cart quantity/coupon/totals/empty, mini-cart, account, checkout, RTL/LTR/dark/mobile, no XShop PHP/JS errors, ZIP installs via Expand-Archive.
---
# M3 — AJAX Search (2026-09-13)
## Endpoint
- `GET /wp-json/xshop/v1/search?search=Test&limit=6` → `200 {"items":[{"id":23,"title":"Out of Stock Test...","url":"...","image":"...","price_html":"...","type":"simple","in_stock":false}],"total":1}` — verified via `Invoke-WebRequest`.
- **Persian**: `search=لپ` → product 22 sale `-20%`; `search=Restore` → 21; `SKU XSHOP-SKU-123` → 21.
- **Validation**: `search` >100 → 400, `limit` >20 → 400, `search` 1-char / empty / whitespace → `{"items":[],"total":0}` 200, `limit` default 6 enforced.
- **Security**: `sanitize_text_field` + `wp_strip_all_tags` + `mb_substr 100`, `absint` 1..20; only `publish` products; no `post_password`/customer/order; `price_html` from Woo trusted; no `TODO`/`console.log`.
- **Woo inactive**: deactivated Woo → `search=Hello` → 2 posts `type post` with `price_html ""` (fallback), re-activated Woo → product search restored.
## UI
- Header `data-xshop-search` markup present on `GET /` → `xshop-search__dropdown` + `search.js` enqueued (`<script id="xshop-search-js" src=".../search.js?ver=1.0.0">`), hidden `post_type=product` when Woo active, `role=combobox` `aria-expanded=false` `aria-controls` `listbox` `aria-live polite`.
- **Dropdown**: `woo.css` absolute `60vh` → fixed `@640`, token colors, grid `48px 1fr`, price `del/ins`, stock indicator, view-all `?s=&post_type=product`.
## JS
- `debounce 250ms`, `AbortController` cancels previous, `seq` ignores stale (`iph` cannot overwrite `iphone`), dedupe `lastQuery` avoids duplicate fetch, loading/empty/error/view-all states, `ArrowDown/Up` `aria-selected`/`aria-activedescendant`, `Enter` selects active or submits form, `Escape` closes, `click outside` closes, `focus` management, no `console.log`, `node --check` pass.
## Accessibility / RTL / Dark / Mobile
- `role=search` + `label.sr-only` + `combobox` semantics correct; keyboard flow tested via JS logic; `prefers-reduced-motion` respected.
- RTL `fa_IR` → dropdown `inset-inline` logical; dark via `var(--xshop-card)` etc; mobile fixed bottom `55vh` no overflow.
## Performance
- `limit 6` bounded, `posts_per_page limit*2` max 40 IDs, `no_found_rows`, `fields ids`, `wc_get_product` only for 6, `Cache-Control: public, max-age=60`, payload ~2KB, `search.js` front-end only (init guard).
## Conclusion
**M3 ACCEPTED** — AJAX search REST + UI + JS + a11y + RTL/dark/mobile + security/performance + Woo on/off + stale protection + canonical search fallback all pass. No private data, no XShop errors.
## Repro
```powershell
Invoke-WebRequest -Uri "http://localhost/xshop-test/wordpress/wp-json/xshop/v1/search?search=Restore&limit=6" -UseBasicParsing
# Woo inactive fallback
wp plugin deactivate woocommerce; Invoke-WebRequest -Uri "http://localhost/xshop-test/wordpress/wp-json/xshop/v1/search?search=Hello&limit=6" -UseBasicParsing
```