4.4 KiB
4.4 KiB
XShop – Database Model
1. Philosophy
Reuse WP/WC primitives. No custom tables in v1.0 – revisit via ADR if query scale warrants. Document every key.
2. WordPress-Owned
- Users (
wp_users,wp_usermeta): native. XShop adds:xshop_wishlist(array of product IDs),xshop_compare(array),xshop_recently_viewed(capped list). - Posts/Pages (
wp_posts,wp_postmeta): native. - Media (
wp_postsattachment): native. - Menus (
wp_termsnav_menu): native. - Comments/Reviews: WC reviews = WP comments on
productpost type. XShop Q&A moderation hooks onto comment moderation flow where applicable – but primary store is custom (below).
3. WooCommerce-Owned
- Products (
wp_postspost_typeproduct+wp_postmeta+wp_wc_*where HPOS enabled). Variations areproduct_variationchildren. - Orders/Customers/Coupons/Shipping/Payment/Taxes/Cart/Checkout: WC owned (HPOS tables if enabled). XShop never writes directly to WC order tables except via WC APIs.
4. XShop-Core Custom Data
4.1 Banners – CPT xshop_banner
post_type = xshop_banner(non-public,show_uitrue under XShop menu).- Meta:
_xshop_banner_image(attachment ID, int)_xshop_banner_mobile_image(attachment ID, int, nullable)_xshop_banner_link(url, esc_url_raw)_xshop_banner_cta(string)_xshop_banner_position(enum:home_hero,home_strip,shop_top,product_sidebar, etc.)_xshop_banner_active(1|0)_xshop_banner_start/_xshop_banner_end(datetime Y-m-d H:i:s, UTC)_xshop_banner_order(int)
- Scheduling checked on render (skip if outside window or inactive).
4.2 Questions & Answers – CPT xshop_qa
Decision: CPT (not comments) for cleaner moderation + threading without polluting reviews.
post_type = xshop_qa,post_parent= product ID (or meta_xshop_qa_product_idfor query flexibility – both stored, parent is canonical).- Post fields:
post_titleempty,post_content= question body,post_status=pending|publish|trash,post_author= asker. - Meta:
_xshop_qa_product_id(int, indexed via meta query)_xshop_qa_answer(string, nullable – single answer for v1; extension to multiple answers uses childxshop_qarows withpost_parent= question ID in v1.1)_xshop_qa_answered_by(int user ID)_xshop_qa_answered_at(datetime)
- Alternative for multiple answers (future): child posts
post_type=xshop_qa,post_parent=question ID. - Spam: honeypot + nonce + rate limit (transient per IP/user, 60s).
4.3 Wishlist & Compare
- Logged-in:
wp_usermetakeysxshop_wishlist,xshop_compare(serialized array of ints, capped: wishlist 200, compare 4). - Guest: cookie
xshop_wishlist/xshop_compare(JSON, HttpOnly false for JS count, SameSite Lax, 30 days) + optional transientxshop_guest_<token>. - On login: merge cookie → user meta (union, cap), clear cookie.
- Counts exposed via REST and localized script data.
4.4 Recently Viewed
- Cookie
xshop_recently_viewed(JSON array of product IDs, capped 20, 30 days). No DB write for guests. Logged-in also stored inxshop_recently_vieweduser meta for cross-device.
5. Options
- Single option
xshop_settings(array) – all Theme Options. Autoloadyes. Individual mods also mirrored viatheme_modfor Customizer preview where needed, but source of truth isxshop_settings. - Option
xshop_settings_backup(for import/export). - Transient
xshop_search_cache_<hash>(5 min) for AJAX search results. - Transient
xshop_filter_counts_<hash>(5 min) for filter counts.
Do NOT scatter random options.
6. Indexes & Query Patterns
- Banners: query by
post_type+ metaposition+active+date range → meta query; small cardinality. - Q&A:
WP_Querybypost_type=xshop_qa+post_parent=product_id+post_status=publish(index onpost_parent+post_typealready exists). - Wishlist/Compare: user meta single-row lookup – O(1).
- Search:
WP_Querywiths+post_type=product+tax_queryfor category,meta_queryfor SKU (_sku), limited to 8 suggestions,no_found_rowstrue,fields=idsthen prime caches.
7. Migrations & Compatibility
- HPOS: use
wc_get_products()/ CRUD, not directwp_postmetawrites for product data. - On plugin deactivate: data retained (no destructive cleanup). Uninstall hook offered to purge (
uninstall.phpwith confirmation).