Files
mataba/shop/docs/ARCHITECTURE.md
T

8.6 KiB
Raw Blame History

XShop – Architecture (v1.0.0)

1. Overview

repo/
  docs/                 # product specs & ADRs
  xshop-theme/          # presentation layer
  xshop-core/           # companion plugin
  release/              # built zips (not committed)
  tools/                # build / QA scripts

Two installable artifacts: theme (xshop) + plugin (xshop-core). Theme never stores business logic that outlives theme activation (wishlist/compare/Q&A/banners live in plugin).

2. Theme – xshop-theme

2.1 File map (M4)

xshop-theme/
  inc/setup/assets.php — tokens→…→woo→utilities + theme.js + search.js + filter.js (front-end, DOM guard, documented)
  inc/woocommerce/setup.php — loop, toolbar, gallery, related, product.js, pre_get_posts no-JS fallback
  assets/css/woo.css — + search + filters (.xshop-shop, _filters, _chip, _drawer, responsive)
  assets/js/search.js — debounce 250ms, AbortController, stale seq
  assets/js/filter.js — URL sync, chips, debounce 300ms for price, AbortController, drawer a11y
  template-parts/components/ajax-search.php + product-filters.php (sidebar+drawer, no-JS fallback)
  woocommerce/archive-product.php — shop/category with filters layout + chips + AJAX grid
xshop-core/
  includes/Query/ProductQuery.php — shared sanitize, map_orderby, build_product_query_args, format_product, execute_query
  includes/REST/Search.php — refactored to use Query
  includes/REST/Products.php — xshop/v1/products (category, pa_*, price, stock, sale, rating, orderby, pagination, search)
  includes/Core/Plugin.php — loads Query + both REST

2.2 Bootstrap

functions.php is a thin loader:

require_once __DIR__ . '/inc/setup/theme-support.php';
require_once __DIR__ . '/inc/setup/menus.php';
// ... each file exposes a single setup function hooked appropriately

No giant functions.php. Each inc/* file is namespaced or prefixed xshop_.

2.3 Namespacing & Prefixing

  • Text domain: xshop
  • PHP functions/options/actions/meta: xshop_ prefix.
  • Classes: XShop\Theme\... and XShop\Core\... (PSR-4 style even if manual require).

2.4 Hook Strategy

  • Use after_setup_theme for theme support, init for CPT/taxonomy (only banners/Q&A).
  • Use wp_enqueue_scripts with conditional loading.
  • Use WC hooks for pricing, badges, loops – avoid overriding templates unless necessary.

3. Plugin – xshop-core

xshop-core/
  xshop-core.php        # plugin header + loader
  includes/
    Core/               # plugin bootstrap, constants
    Modules/
      Wishlist/
      Compare/
      QA/
      Search/
      Filter/
      Banners/
      Badges/
      DemoImport/
      SetupWizard/
      SystemStatus/
      Widgets/
    Admin/              # menu, dashboard, settings pages
    REST/               # REST endpoints (search/filter/wishlist/compare/QA)
    Compatibility/
  assets/ css/ js/
  languages/
  templates/            # wishlist, compare, banners front-end fragments

Plugin owns persistence for wishlist/compare/Q&A/banners. Theme only renders.

4. Data Ownership

  • WC: products, variations, orders, customers, coupons, shipping, payment, taxes, cart, checkout.
  • WP: users, posts, pages, media, menus, comments.
  • Custom: banners (CPT xshop_banner), Q&A (CPT or comments extension – see DATABASE-MODEL.md), wishlist/compare (user meta + cookie + transient for guests), theme settings (single option xshop_settings + mods).

Avoid custom tables in v1; revisit via ADR if scale demands.

5. Design System (M2)

Tokens: tokens.css unchanged — adds WC tokens --xshop-wc-badge-sale/--xshop-wc-price etc. Layering tokens→base→layout→components→woo→utilities→style.css (woo.css 159 lines, tokens for shop/product/cart). Dark mode semantic swap covers bg/surface/card/text/muted/border/input/focus/link/notice — verified on shop/card/gallery/tabs/cart/checkout. Logical props only, zero left/right.

6. Asset Strategy (M2)

  • Vanilla JS: theme.js (deferred) + product.js (enqueued only on is_product() via xshop_wc_single_setup guard). No gallery framework, 40 lines, keyboard Arrow/Home/End.
  • Enqueue: tokens→base→layout→components→woo→utilities→style.css chain in inc/setup/assets.php:1 (woo.css intentionally global 12KB — replaces Woo's 3 stylesheets, avoids FOUC on shop/product/cart/account; documented, tiny vs conditional complexity). WC styles dequeued (woocommerce_enqueue_styles → __return_empty_array). product.js conditional, comment-reply conditional.
  • 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 (M4)

  • Search (M3): GET /wp-json/xshop/v1/search?search=&limit= — public, search max 100 + limit 1..20, min 2, WP_Query s + _sku LIKE, publish only, no_found_rows fields ids, {items:[id,title,url,image,price_html,type,in_stock],total} + Cache-Control: public, max-age=60, shared Query\ProductQuery.
  • Products (M4): GET /wp-json/xshop/v1/products?search=&category=&pa_*=&min_price=&max_price=&stock=&on_sale=&rating=&orderby=&page=&per_page= — public, sanitized search + category slug/ID + dynamic pa_* (only taxonomy_exists), min/max numeric 0..99M + min<=max 400, stock all/instock/outofstock, on_sale 0/1 via meta OR, rating 0..5 via _wc_average_rating, orderby allow-list default/latest/price_asc/desc/popularity/rating/date → map_orderby, page 1..100 per_page 1..24 default 12, shared ProductQuery::build_product_query_args → WP_Query tax_query + meta_query + orderby + post__in for sale, execute_query → {items, pagination:{page,per_page,total,total_pages}} + Cache-Control: public, max-age=30, no private data, no N+1.
  • Prefer REST for search/filter, fallback admin-ajax for cart.

8. Security Model

See SECURITY.md. TL;DR: sanitize in, escape out, nonces, capability checks, prepared statements, no unserialize, no open redirects.

9. Performance Model

See PERFORMANCE.md. Conditional assets, lazy-load, transients for expensive queries, no N+1, wp_cache.

10. i18n / RTL

  • All strings via __(), _e(), esc_html__() with text domain xshop.
  • Logical CSS, dir attribute toggling, is_rtl() branching only where logical props insufficient.
  • Persian typography tokens, lang="fa" support, mixed LTR numbers handled via unicode-bidi where needed.

11. Templating (M2)

header.php → site-header + breadcrumbs; footer.php → site-footer. Content templates use Loop + get_template_part. Reusable: product-card.php:1 (WC_Product badges/price/rating, hook xshop_product_card_after_actions), product-grid.php:1, product-gallery.php:1 (featured+thumbs, keyboard). front-page.php section-based via xshop_front_hero_args.

Woo overrides (4, all minimal, versioned):

  • woocommerce/content-product.php (3.6.0) — Why: grid/token alignment; Hooks/CSS insufficient (li.product markup). Minimal: single <li> + get_template_part product-card. Risk: Woo 3.6 → bump → re-check wc_product_class.
  • woocommerce/archive-product.php (3.4.0) — Why: XShop header (category title/desc/count) + toolbar + empty-state CTA. Hooks could do header but empty-state needs override. Minimal.
  • woocommerce/content-single-product.php (3.6.0) — Why: grid layout .xshop-product gallery+summary + custom gallery component. Hooks alone can't provide grid wrapper without CSS hacks. Minimal: wraps hooks, replaces woocommerce_show_product_images.
  • woocommerce/single-product.php (1.6.4) — Delegator to content-single-product.php; kept for explicitness, could be removed (Woo default works) but retained for clarity.

All keep Woo hooks (woocommerce_before_single_product, woocommerce_single_product_summary, woocommerce_after_single_product_summary etc.) — no business logic rewrite. inc/woocommerce/setup.php:1 handles loop_start/end filter (xshop-products), toolbar woocommerce_before_shop_loop 9/35, remove gallery, related args posts_per_page 4 columns 4.

12. Decision Records

ADRs in docs/ADR/ – one per major decision (e.g., “No custom tables for Q&A in v1”).

13. Release

release/xshop.zip + release/xshop-core.zip built via tools/build-release.ps1. Excludes .git, node_modules, .env, logs, temp.

14. Versioning

SemVer 1.0.0. CHANGELOG.md follows Keep a Changelog.

15. Risks & Mitigations

  • WC API churn → pin tested versions, monitor template versions, use hooks not overrides.
  • RTL regressions → logical props + visual regression checklist.
  • Demo import timeouts → chunked importer with resume.