From f11e1d650da9ca25d6f186b659023aea8a1c08d7 Mon Sep 17 00:00:00 2001 From: XShop Date: Sun, 13 Sep 2026 19:04:41 +0330 Subject: [PATCH] chore: complete M1.1 runtime QA and release packaging --- shop/.editorconfig | 15 ++ shop/.gitignore | 16 ++ shop/CHANGELOG.md | 16 ++ shop/README.md | 40 +++++ shop/docs/ADR/001-no-custom-tables-v1.md | 17 ++ shop/docs/ADR/002-rest-over-admin-ajax.md | 17 ++ shop/docs/ARCHITECTURE.md | 163 ++++++++++++++++++ shop/docs/COMPATIBILITY.md | 46 +++++ shop/docs/DATABASE-MODEL.md | 80 +++++++++ shop/docs/FEATURE-MATRIX.md | 95 ++++++++++ shop/docs/PERFORMANCE.md | 49 ++++++ shop/docs/PRODUCT-SPEC.md | 90 ++++++++++ shop/docs/ROADMAP.md | 60 +++++++ shop/docs/RUNTIME-QA.md | 118 +++++++++++++ shop/docs/SECURITY.md | 64 +++++++ shop/docs/TESTING.md | 61 +++++++ shop/docs/UI-SPEC.md | 92 ++++++++++ shop/tools/build-release.ps1 | 41 +++++ shop/xshop-core/includes/Core/Plugin.php | 74 ++++++++ .../includes/Modules/Banners/CPT.php | 90 ++++++++++ shop/xshop-core/includes/Modules/QA/CPT.php | 24 +++ shop/xshop-core/xshop-core.php | 33 ++++ shop/xshop-theme/404.php | 39 +++++ shop/xshop-theme/archive.php | 36 ++++ shop/xshop-theme/assets/css/base.css | 36 ++++ shop/xshop-theme/assets/css/components.css | 90 ++++++++++ shop/xshop-theme/assets/css/layout.css | 82 +++++++++ shop/xshop-theme/assets/css/tokens.css | 91 ++++++++++ shop/xshop-theme/assets/css/utilities.css | 10 ++ shop/xshop-theme/assets/js/theme.js | 82 +++++++++ shop/xshop-theme/comments.php | 73 ++++++++ shop/xshop-theme/footer.php | 20 +++ shop/xshop-theme/front-page.php | 105 +++++++++++ shop/xshop-theme/functions.php | 30 ++++ shop/xshop-theme/header.php | 36 ++++ .../inc/compatibility/elementor.php | 16 ++ .../inc/compatibility/gutenberg.php | 10 ++ .../xshop-theme/inc/customization/options.php | 61 +++++++ shop/xshop-theme/inc/helpers/sanitize.php | 21 +++ shop/xshop-theme/inc/helpers/template.php | 53 ++++++ shop/xshop-theme/inc/performance/loader.php | 18 ++ shop/xshop-theme/inc/setup/assets.php | 37 ++++ shop/xshop-theme/inc/setup/body-classes.php | 22 +++ shop/xshop-theme/inc/setup/menus.php | 14 ++ shop/xshop-theme/inc/setup/sidebars.php | 27 +++ shop/xshop-theme/inc/setup/theme-support.php | 29 ++++ shop/xshop-theme/inc/woocommerce/setup.php | 37 ++++ shop/xshop-theme/index.php | 35 ++++ shop/xshop-theme/page.php | 50 ++++++ shop/xshop-theme/rtl.css | 2 + shop/xshop-theme/screenshot.png | 1 + shop/xshop-theme/search.php | 43 +++++ shop/xshop-theme/sidebar.php | 23 +++ shop/xshop-theme/single.php | 78 +++++++++ shop/xshop-theme/style.css | 16 ++ .../template-parts/components/breadcrumbs.php | 113 ++++++++++++ .../template-parts/components/empty-state.php | 23 +++ .../template-parts/components/hero.php | 27 +++ .../template-parts/components/loading.php | 17 ++ .../template-parts/components/pagination.php | 41 +++++ .../template-parts/components/post-card.php | 45 +++++ .../components/promo-banner.php | 26 +++ .../template-parts/components/search-form.php | 20 +++ .../components/section-heading.php | 25 +++ .../template-parts/components/site-footer.php | 53 ++++++ .../template-parts/components/site-header.php | 80 +++++++++ 66 files changed, 3094 insertions(+) create mode 100644 shop/.editorconfig create mode 100644 shop/.gitignore create mode 100644 shop/CHANGELOG.md create mode 100644 shop/README.md create mode 100644 shop/docs/ADR/001-no-custom-tables-v1.md create mode 100644 shop/docs/ADR/002-rest-over-admin-ajax.md create mode 100644 shop/docs/ARCHITECTURE.md create mode 100644 shop/docs/COMPATIBILITY.md create mode 100644 shop/docs/DATABASE-MODEL.md create mode 100644 shop/docs/FEATURE-MATRIX.md create mode 100644 shop/docs/PERFORMANCE.md create mode 100644 shop/docs/PRODUCT-SPEC.md create mode 100644 shop/docs/ROADMAP.md create mode 100644 shop/docs/RUNTIME-QA.md create mode 100644 shop/docs/SECURITY.md create mode 100644 shop/docs/TESTING.md create mode 100644 shop/docs/UI-SPEC.md create mode 100644 shop/tools/build-release.ps1 create mode 100644 shop/xshop-core/includes/Core/Plugin.php create mode 100644 shop/xshop-core/includes/Modules/Banners/CPT.php create mode 100644 shop/xshop-core/includes/Modules/QA/CPT.php create mode 100644 shop/xshop-core/xshop-core.php create mode 100644 shop/xshop-theme/404.php create mode 100644 shop/xshop-theme/archive.php create mode 100644 shop/xshop-theme/assets/css/base.css create mode 100644 shop/xshop-theme/assets/css/components.css create mode 100644 shop/xshop-theme/assets/css/layout.css create mode 100644 shop/xshop-theme/assets/css/tokens.css create mode 100644 shop/xshop-theme/assets/css/utilities.css create mode 100644 shop/xshop-theme/assets/js/theme.js create mode 100644 shop/xshop-theme/comments.php create mode 100644 shop/xshop-theme/footer.php create mode 100644 shop/xshop-theme/front-page.php create mode 100644 shop/xshop-theme/functions.php create mode 100644 shop/xshop-theme/header.php create mode 100644 shop/xshop-theme/inc/compatibility/elementor.php create mode 100644 shop/xshop-theme/inc/compatibility/gutenberg.php create mode 100644 shop/xshop-theme/inc/customization/options.php create mode 100644 shop/xshop-theme/inc/helpers/sanitize.php create mode 100644 shop/xshop-theme/inc/helpers/template.php create mode 100644 shop/xshop-theme/inc/performance/loader.php create mode 100644 shop/xshop-theme/inc/setup/assets.php create mode 100644 shop/xshop-theme/inc/setup/body-classes.php create mode 100644 shop/xshop-theme/inc/setup/menus.php create mode 100644 shop/xshop-theme/inc/setup/sidebars.php create mode 100644 shop/xshop-theme/inc/setup/theme-support.php create mode 100644 shop/xshop-theme/inc/woocommerce/setup.php create mode 100644 shop/xshop-theme/index.php create mode 100644 shop/xshop-theme/page.php create mode 100644 shop/xshop-theme/rtl.css create mode 100644 shop/xshop-theme/screenshot.png create mode 100644 shop/xshop-theme/search.php create mode 100644 shop/xshop-theme/sidebar.php create mode 100644 shop/xshop-theme/single.php create mode 100644 shop/xshop-theme/style.css create mode 100644 shop/xshop-theme/template-parts/components/breadcrumbs.php create mode 100644 shop/xshop-theme/template-parts/components/empty-state.php create mode 100644 shop/xshop-theme/template-parts/components/hero.php create mode 100644 shop/xshop-theme/template-parts/components/loading.php create mode 100644 shop/xshop-theme/template-parts/components/pagination.php create mode 100644 shop/xshop-theme/template-parts/components/post-card.php create mode 100644 shop/xshop-theme/template-parts/components/promo-banner.php create mode 100644 shop/xshop-theme/template-parts/components/search-form.php create mode 100644 shop/xshop-theme/template-parts/components/section-heading.php create mode 100644 shop/xshop-theme/template-parts/components/site-footer.php create mode 100644 shop/xshop-theme/template-parts/components/site-header.php diff --git a/shop/.editorconfig b/shop/.editorconfig new file mode 100644 index 0000000..ec48fee --- /dev/null +++ b/shop/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 4 + +[*.{js,css,json,yml,yaml}] +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false diff --git a/shop/.gitignore b/shop/.gitignore new file mode 100644 index 0000000..8b231d6 --- /dev/null +++ b/shop/.gitignore @@ -0,0 +1,16 @@ +release/*.zip +release/*.log +# Local test installs (M1.1) – never commit wp-config / debug logs / DB +xshop-test/ +wp-config.php +debug.log +node_modules/ +vendor/ +.env +.env.* +*.log +.DS_Store +Thumbs.db +.cache/ +coverage/ +.sass-cache/ diff --git a/shop/CHANGELOG.md b/shop/CHANGELOG.md new file mode 100644 index 0000000..284b084 --- /dev/null +++ b/shop/CHANGELOG.md @@ -0,0 +1,16 @@ +# Changelog + +All notable changes to XShop follow [Keep a Changelog](https://keepachangelog.com/) and [SemVer](https://semver.org/). + +## [1.0.0] – Unreleased + +### Added +- Phase 0: product spec, architecture, feature matrix, roadmap, UI spec, database model, security, performance, testing, compatibility docs + ADRs. +- **M1 — Theme Foundation**: + - Templates: `header.php`, `footer.php`, `index.php`, `front-page.php` (section-based hero/category/product/promo/latest), `single.php`, `page.php`, `archive.php`, `search.php`, `404.php`, `sidebar.php`, `comments.php` (threaded, paginated, accessible). + - Components: `template-parts/components/site-header.php`, `site-footer.php`, `breadcrumbs.php` (Woo-aware, filterable), `pagination.php` (RTL-safe), `search-form.php`, `post-card.php`, `empty-state.php`, `loading.php`, `section-heading.php`, `hero.php`, `promo-banner.php`. + - Design system: finalized `assets/css/tokens.css` (full palette/typography/spacing/radius/shadow/z/transition + dark mode semantic swap), `base.css`, `layout.css`, `components.css`, `utilities.css` — logical properties, zero `left`/`right`. + - JS: `assets/js/theme.js` extended with accessible mobile nav (aria-expanded, focus trap, Esc, click-outside) + dark-mode toggle. + - PHP: `inc/helpers/template.php` (xshop_has_woocommerce, xshop_is_woocommerce_page, branding fallback), `inc/setup/body-classes.php`, `inc/setup/assets.php` (layered enqueue + Woo style dequeue), `inc/woocommerce/setup.php` (wrappers). + - Docs: updated `docs/ARCHITECTURE.md`, `docs/UI-SPEC.md`, `docs/TESTING.md` for M1. + diff --git a/shop/README.md b/shop/README.md new file mode 100644 index 0000000..e587fa2 --- /dev/null +++ b/shop/README.md @@ -0,0 +1,40 @@ +# XShop — Persian-first WooCommerce Theme + Companion Plugin + +Commercial, RTL/LTR, responsive, accessible, performant. Sold on RTL-Theme / راست‌چین. + +## Components + +- `xshop-theme/` — presentation (templates, design system, RTL, header/footer builders). +- `xshop-core/` — functionality (wishlist, compare, Q&A, AJAX search/filter, banners, demo import). + +## Docs + +- `docs/PRODUCT-SPEC.md` — product spec +- `docs/ARCHITECTURE.md` — architecture +- `docs/FEATURE-MATRIX.md` — feature matrix +- `docs/ROADMAP.md` — roadmap & phases +- `docs/UI-SPEC.md` — design system +- `docs/DATABASE-MODEL.md` — data model +- `docs/SECURITY.md` — security +- `docs/PERFORMANCE.md` — performance +- `docs/TESTING.md` — testing +- `docs/COMPATIBILITY.md` — compatibility +- `docs/ADR/` — architecture decision records + +## Requirements + +- WordPress 6.4+, WooCommerce 8.0+, PHP 8.2+, modern browsers. + +## Quick Start (dev) + +1. Copy `xshop-theme/` to `wp-content/themes/xshop/`. +2. Copy `xshop-core/` to `wp-content/plugins/xshop-core/`. +3. Activate theme + plugin. Run setup wizard (XShop → Setup Wizard). + +## Development Principles + +See `docs/ARCHITECTURE.md` and `AGENTS.md` (if present). No TODO placeholders in releases. WC is source of truth for commerce; WP for content. + +## License + +Commercial. Third-party assets documented in `xshop-theme/docs/` and `CHANGELOG.md`. diff --git a/shop/docs/ADR/001-no-custom-tables-v1.md b/shop/docs/ADR/001-no-custom-tables-v1.md new file mode 100644 index 0000000..710b0c7 --- /dev/null +++ b/shop/docs/ADR/001-no-custom-tables-v1.md @@ -0,0 +1,17 @@ +# ADR 001 – No Custom Tables in v1 + +**Status**: Accepted + +## Context + +Wishlist/compare/Q&A/banners could use custom tables for performance. Customs add migration/upgrade burden and risk for a commercial theme sold on RTL-Theme where host environments vary. + +## Decision + +Store all v1 data in WP primitives: CPT (`xshop_banner`, `xshop_qa`), `wp_usermeta` + cookies for wishlist/compare, single option `xshop_settings`. No custom tables. + +## Consequences + +- Simpler install/uninstall, no `dbDelta` fragility. +- Query performance acceptable at ≤100k products; revisit if profiling shows bottleneck. +- Future ADR can introduce tables with migration path. diff --git a/shop/docs/ADR/002-rest-over-admin-ajax.md b/shop/docs/ADR/002-rest-over-admin-ajax.md new file mode 100644 index 0000000..a10cdda --- /dev/null +++ b/shop/docs/ADR/002-rest-over-admin-ajax.md @@ -0,0 +1,17 @@ +# ADR 002 – REST API as Primary for AJAX + +**Status**: Accepted + +## Context + +Search/filter/wishlist/compare/Q&A need async endpoints. `admin-ajax.php` is uncacheable and fires `admin_init`. REST is cache-friendly and has `permission_callback`. + +## Decision + +- REST (`xshop/v1/*`) for search, filter, wishlist, compare, Q&A. +- Keep `admin-ajax` only where WC core expects it (cart fragments/mini-cart) or as fallback. + +## Consequences + +- Requires nonce via `X-WP-Nonce` + localized `wpApiSettings` or custom `xshopData.nonce`. +- Better compatibility with caching plugins; clearer permission model. diff --git a/shop/docs/ARCHITECTURE.md b/shop/docs/ARCHITECTURE.md new file mode 100644 index 0000000..9cd19f7 --- /dev/null +++ b/shop/docs/ARCHITECTURE.md @@ -0,0 +1,163 @@ +# 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 (M1) + +``` +xshop-theme/ + style.css # WP header + functions.php # thin loader (requires inc/setup/* only) + screenshot.png # placeholder until final artwork + rtl.css # WP RTL flag; logical props used, not duplicated stylesheet + header.php # + skip link + xshop-header wrapper + breadcrumbs + footer.php # + footer + wp_footer + index.php / front-page.php / single.php / page.php / archive.php / search.php / 404.php / sidebar.php / comments.php + inc/ + setup/ # theme-support, menus, sidebars, body-classes, assets + helpers/ # sanitize, template (xshop_get_setting, xshop_svg, xshop_is_dark_mode, xshop_has_woocommerce, branding fallback) + customization/ # options (xshop_settings) — full UI in M6 + compatibility/ # gutenberg, elementor (no hard dep) + woocommerce/ # wrappers + dequeued WC styles + notice compat + performance/ # defer for xshop.js + assets/ + css/ # tokens, base, layout, components, utilities + js/ # theme.js (mobile nav + dark toggle + focus trap) + images/ fonts/ + template-parts/components/ + site-header.php, site-footer.php, + breadcrumbs.php, pagination.php, search-form.php, post-card.php, + empty-state.php, loading.php, section-heading.php, hero.php, promo-banner.php + woocommerce/ # empty in M1 — overrides only when justified (documented) + languages/ +``` + +### 2.2 Bootstrap + +`functions.php` is a thin loader: + +```php +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 (M1) + +CSS custom properties in `assets/css/tokens.css` — full token set: primary/secondary/bg/surface/card/text/muted/border/input/focus/link/success/warning/danger (+ bg variants), typography (xs–4xl, weights 400/500/700, leading tight/normal/relaxed), spacing (1–16), container/narrow, radius (sm/md/lg/full), shadow (sm/md/lg), z, transition (fast/normal/slow). Dark mode semantic swap on `[data-theme="dark"]`. Layering: `tokens→base→layout→components→utilities→style.css` via `inc/setup/assets.php:1`. + +Logical properties (`margin-inline`, `padding-inline`, `inset-inline`, `inset-block`, `inline-size`) throughout; zero `left`/`right` in theme CSS. Components consume tokens, never hardcode colours. + +## 6. Asset Strategy (M1) + +- No jQuery for new code (vanilla JS; `theme.js:1` is deferred). WC jQuery remains for its handlers. +- Enqueue: `tokens→base→layout→components→utilities→style.css` chain in `inc/setup/assets.php:1` with version `XSHOP_VERSION`; `style.css` declares `rtl` replace. WC styles dequeued (`woocommerce_enqueue_styles` → `__return_empty_array`) to avoid duplication — theme provides compat in `components.css:1`. +- Conditional: feature modules (search/filter/wishlist) will be enqueued per-template in M5; M1 only loads `theme.js`. +- Localized `xshopData` (restUrl, nonce, isRtl, i18n) on `xshop` handle. +- Build: no build step required to activate; release minify via `tools/build-release.ps1`. + +## 7. AJAX / REST + +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. + +## 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 (M1) + +`header.php:1` renders `site-header.php:1` + `breadcrumbs:1` (except front/404); `footer.php:1` renders `site-footer.php:1`. All content templates (`index.php:1`, `front-page.php:1`, `single.php:1`, `page.php:1`, `archive.php:1`, `search.php:1`, `404.php:1`) use Loop + `get_template_part()` + `comments_template()` / `dynamic_sidebar()` where appropriate. Reusable components: `breadcrumbs`, `pagination`, `search-form`, `post-card`, `empty-state`, `loading`, `section-heading`, `hero`, `promo-banner`. No markup duplication. `front-page.php:1` is section-based (hero, category grid, product grid via `wc_get_products`, promo, latest posts) — extensible via `xshop_front_hero_args` filter. + +WC overrides: none in M1; wrappers via `woocommerce_before_main_content`/`after_main_content` in `inc/woocommerce/setup.php:1`. Future overrides documented in `docs/woocommerce.md` with version map. + +## 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. diff --git a/shop/docs/COMPATIBILITY.md b/shop/docs/COMPATIBILITY.md new file mode 100644 index 0000000..62f4f4d --- /dev/null +++ b/shop/docs/COMPATIBILITY.md @@ -0,0 +1,46 @@ +# XShop – Compatibility + +## 1. Tested Up To + +| Dependency | Minimum | Tested | +|------------|---------|--------| +| WordPress | 6.4 | 6.6.x | +| WooCommerce| 8.0 | 9.x | +| PHP | 8.2 | 8.2, 8.3 | +| Elementor | 3.15 (optional) | 3.2x | +| Gutenberg | WP bundled | — | +| Browsers | last 2 versions: Chrome, Firefox, Edge, Safari | — | + +## 2. WordPress APIs Used + +- Theme support: `add_theme_support('title-tag','post-thumbnails','html5','custom-logo','woocommerce'...)` +- Menus/sidebars/widgets: `register_nav_menus`, `register_sidebar`, `widgets_init`. +- Settings: `register_setting` + single option `xshop_settings` (Settings API). +- Customizer: `customize_register` for preview (typography/colours). +- REST: `register_rest_route` (namespace `xshop/v1`). + +## 3. WooCommerce Integration + +- Declared `add_theme_support('woocommerce')` + gallery features (`wc-product-gallery-zoom/lightbox/slider`). +- Wrapper via `woocommerce_before_main_content` / `after_main_content`. +- Hooks over template overrides. Overrides documented in `docs/woocommerce.md` with WC version map; monitor `WC()->version` and template `Version:` header. + +## 4. HPOS + +- Uses `wc_get_products` CRUD, not direct post table writes. Compatible with High-Performance Order Storage. No direct `wp_posts` manipulation for orders. + +## 5. Elementor + +- Widgets registered via `\Elementor\Plugin::instance()->widgets_manager->register` if Elementor active. Namespaced `XShop\Core\Elementor\Widgets\*`. No hard dependency – `is_plugin_active` guard. + +## 6. Gutenberg + +- Block styles via `register_block_style`, theme.json opt-in later. No classic-editor dependency. + +## 7. Multisite + +- Not primary target; options are per-site (no network options in v1). + +## 8. Upgrade Notes + +- Template version bumps checked via `WC template version` comment. Override only where necessary; changelog notes any override update. diff --git a/shop/docs/DATABASE-MODEL.md b/shop/docs/DATABASE-MODEL.md new file mode 100644 index 0000000..e439dd2 --- /dev/null +++ b/shop/docs/DATABASE-MODEL.md @@ -0,0 +1,80 @@ +# 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_posts` attachment): native. +- **Menus** (`wp_terms` nav_menu): native. +- **Comments/Reviews**: WC reviews = WP comments on `product` post type. XShop Q&A moderation hooks onto comment moderation flow where applicable – but primary store is custom (below). + +## 3. WooCommerce-Owned + +- **Products** (`wp_posts` post_type `product` + `wp_postmeta` + `wp_wc_*` where HPOS enabled). Variations are `product_variation` children. +- **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_ui` true 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_id` for query flexibility – both stored, parent is canonical). +- Post fields: `post_title` empty, `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 child `xshop_qa` rows with `post_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_usermeta` keys `xshop_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 transient `xshop_guest_`. +- 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 in `xshop_recently_viewed` user meta for cross-device. + +## 5. Options + +- Single option `xshop_settings` (array) – all Theme Options. Autoload `yes`. Individual mods also mirrored via `theme_mod` for Customizer preview where needed, but source of truth is `xshop_settings`. +- Option `xshop_settings_backup` (for import/export). +- Transient `xshop_search_cache_` (5 min) for AJAX search results. +- Transient `xshop_filter_counts_` (5 min) for filter counts. + +Do NOT scatter random options. + +## 6. Indexes & Query Patterns + +- Banners: query by `post_type` + meta `position`+`active`+date range → meta query; small cardinality. +- Q&A: `WP_Query` by `post_type=xshop_qa` + `post_parent=product_id` + `post_status=publish` (index on `post_parent` + `post_type` already exists). +- Wishlist/Compare: user meta single-row lookup – O(1). +- Search: `WP_Query` with `s` + `post_type=product` + `tax_query` for category, `meta_query` for SKU (`_sku`), limited to 8 suggestions, `no_found_rows` true, `fields=ids` then prime caches. + +## 7. Migrations & Compatibility + +- HPOS: use `wc_get_products()` / CRUD, not direct `wp_postmeta` writes for product data. +- On plugin deactivate: data retained (no destructive cleanup). Uninstall hook offered to purge (`uninstall.php` with confirmation). diff --git a/shop/docs/FEATURE-MATRIX.md b/shop/docs/FEATURE-MATRIX.md new file mode 100644 index 0000000..6838b25 --- /dev/null +++ b/shop/docs/FEATURE-MATRIX.md @@ -0,0 +1,95 @@ +# XShop – Feature Matrix (v1.0.0) + +Legend: ✅ v1.0 · 🔜 v1.x · ❌ out-of-scope + +## Frontend Pages + +| Page | Status | Notes | +|------|--------|-------| +| Home | ✅ | Hero, promos, category grid, product carousels, banners | +| Shop / Archive | ✅ | Grid/list, filters, sort, pagination | +| Category | ✅ | Same as shop, category header | +| Tag / Archive | ✅ | — | +| Search Results | ✅ | AJAX search + fallback | +| Single Product | ✅ | Gallery/zoom, variations, badges, tabs, Q&A | +| Cart | ✅ | WC cart + cross-sells | +| Checkout | ✅ | WC checkout, coupons, shipping | +| Order Received | ✅ | WC thank-you | +| My Account | ✅ | WC account endpoints | +| Login / Register / Lost Password | ✅ | WC forms | +| Wishlist | ✅ | `xshop-core`, guest+auth | +| Compare | ✅ | Table view | +| Blog + Single | ✅ | — | +| Page / About / Contact | ✅ | Gutenberg-compatible | +| 404 | ✅ | Search + recent products | + +## Product Features + +| Feature | Status | +|---------|--------| +| Simple / Variable / Attributes / Variations | ✅ | +| Gallery + Zoom + Lightbox | ✅ | +| Sale/Regular price, Stock, Quantity, Add-to-cart | ✅ | +| Buy Now | ✅ | +| Wishlist / Compare / Quick View | ✅ | +| Recently Viewed / Related / Upsells / Cross-sells | ✅ | +| Reviews | ✅ (WC) | +| Q&A | ✅ | +| Badges / Labels | ✅ | + +## Shop Features + +| Feature | Status | +|---------|--------| +| AJAX search (title/SKU/category/tag) | ✅ | +| Category / Attribute / Price / Stock / Sale / Rating filters | ✅ | +| Sorting / Pagination / Load More | ✅ | +| Grid/List toggle / Result count / Active chips / Clear | ✅ | + +## Header / Footer / Navigation + +| Feature | Status | +|---------|--------| +| Desktop + Mobile header, Top bar, Sticky | ✅ | +| Search / Account / Wishlist / Cart / Mini-cart | ✅ | +| Navigation + Mega Menu | ✅ | +| Mobile bottom nav | ✅ | +| Footer builder (columns/menus/social/copyright/custom) | ✅ | + +## Design + +| Feature | Status | +|---------|--------| +| RTL + LTR, Responsive/mobile-first | ✅ | +| Typography / Colour / Spacing / Radius / Shadows / Z-index tokens | ✅ | +| Dark mode (tokens) | ✅ | +| Multiple header/footer/product-card layouts | ✅ (≥2 each) | + +## Admin / Companion + +| Feature | Status | +|---------|--------| +| Theme Options (General/Header/Footer/Typography/Colors/Shop/Product/Blog/Woo/Social/Performance/Custom CSS) | ✅ | +| Header/Footer Builder (config-based) | ✅ | +| Mega Menu manager | ✅ | +| Banner Manager | ✅ | +| Wishlist / Compare / Q&A / Badges | ✅ | +| AJAX Search / Filter | ✅ | +| Demo Import + Setup Wizard + System Status + Import/Export | ✅ | +| Extra widgets/components | ✅ | + +## Integrations + +| Integration | Status | +|-------------|--------| +| WooCommerce 8.0+ | ✅ | +| Gutenberg | ✅ | +| Elementor (optional, widgets in xshop-core) | ✅ | + +## AJAX Candidates + +search, filter, add-to-cart, mini-cart, wishlist, compare, quantity, remove-item, quick-view — all nonce-protected, loading/error states. + +## v1.x Candidates + +Subscriptions sub, multi-vendor, advanced analytics, PWA – via ADR. diff --git a/shop/docs/PERFORMANCE.md b/shop/docs/PERFORMANCE.md new file mode 100644 index 0000000..bfe0fcf --- /dev/null +++ b/shop/docs/PERFORMANCE.md @@ -0,0 +1,49 @@ +# XShop – Performance + +## 1. Budgets + +- LCP < 2.5s on mid-tier mobile (4G, Moto G4 class). +- Total blocking JS < 150ms. +- No render-blocking webfont swap beyond FOIT 100ms (use `font-display: swap`). +- DB queries: shop archive < 12 queries, product < 15 (WC baseline excluded). + +## 2. Assets + +- **Conditional enqueue**: each module (`search`, `filter`, `gallery`, `wishlist`) enqueued only where needed (`is_shop`, `is_product`, `is_search`, or presence of shortcode/block). +- **No global JS**: single `xshop.js` is ~5KB bootstrap; feature modules lazy-imported via `import()`. +- **CSS**: tokens + base always; component CSS split but concatenated in release (critical inline optional, not required v1). +- **No jQuery** for new code; WC jQuery remains for its own handlers. +- **Images**: `loading="lazy"` + `decoding="async"` + `srcset`, hero eager. Thumbnails via `wp_get_attachment_image`. +- **Fonts**: system stack default; optional Vazirmatn self-hosted, subset, no external request by default. + +## 3. Queries + +- Avoid N+1: prime post caches (`update_post_meta_cache`, `update_post_term_cache`), use `wc_get_products` with `return => ids` where only IDs needed, then `wc_get_product` in loop. +- Cache expensive counts: filter counts via transient (5 min), search suggestions via transient (5 min). +- No queries on `init` for frontend; defer to template. + +## 4. Caching + +- Transients for search/filter counts; `wp_cache` for in-request repeated lookups (e.g., `xshop_get_setting`). +- Compatibility with WP Rocket / LiteSpeed – no `DONOTCACHEPAGE` abuse. + +## 5. Minification + +- Release build minifies CSS/JS (`tools/build-release.ps1` runs cssnano/terser or PHP minify). Source maps for dev. + +## 6. DOM + +- Minimal wrappers, no deep nesting. No layout thrash (batch DOM reads/writes). +- Carousel: CSS scroll-snap, no heavy JS. + +## 7. Monitoring + +- `System Status` reports: PHP/WP/WC versions, active plugins, asset sizes, transient hit rate. +- Lighthouse CI optional (not required for v1). + +## 8. Anti-Patterns Forbidden + +- Global `wp_enqueue_script` without condition. +- Querying all products to compute filters. +- Unbounded `WP_Query` without `posts_per_page` / `no_found_rows`. +- External fonts/CDNs by default. diff --git a/shop/docs/PRODUCT-SPEC.md b/shop/docs/PRODUCT-SPEC.md new file mode 100644 index 0000000..a6e9c81 --- /dev/null +++ b/shop/docs/PRODUCT-SPEC.md @@ -0,0 +1,90 @@ +# XShop – Product Specification (v1.0.0) + +> Persian-first commercial WooCommerce theme. Original implementation, inspired by UX quality of modern Persian e-commerce themes such as BantaShop. Zero copying of source, assets, or branding from references. + +## 1. Vision + +XShop is a premium, performant, RTL/LTR, responsive WooCommerce theme + companion plugin (`xshop-core`) sold on RTL-Theme / راست‌چین. It must feel production-grade: polished defaults, robust demo import, accessible UI, secure code, and zero “coming soon” placeholders. + +## 2. Non-goals + +- Not a page-builder theme that forces Elementor. +- Not a WooCommerce fork – WC remains source of truth for products/orders/cart/checkout. +- Not a SaaS – fully self-hosted WordPress. + +## 3. Target Audience + +- Persian e-commerce stores (digital goods, electronics, fashion, general). +- Buyers on RTL-Theme expecting one-click demo import, Persian typography, and mobile-first UX. +- Developers extending via hooks/filters. + +## 4. Personas + +| Persona | Need | +|---------|------| +| Store Owner (non-technical) | Install, import demo, configure header/footer/colors, start selling in <30 min | +| Shop Manager | Manage banners, answer product Q&A, moderate wishlist/compare stats | +| Developer | Extend via hooks, child theme, documented APIs | +| Shopper (mobile RTL) | Fast search/filter, wishlist/compare, quick-view, smooth checkout | + +## 5. Scope – Two Components + +### 5.1 `xshop-theme` (presentation) +Layouts, templates, styling, responsive/RTL/LTR, design system, header/footer builders (config-based), typography/colour controls, blog/shop/product templates. + +### 5.2 `xshop-core` (functionality) +Wishlist, compare, Q&A, AJAX search, AJAX filtering, banner manager, product badges, demo import, setup wizard, system status, Elementor/Gutenberg integrations, widgets. + +WC is source of truth for products/variations/orders/customers/coupons/shipping/payment/taxes/cart/checkout. WP is source of truth for users/posts/pages/media/menus/comments. + +## 6. User Stories (excerpt) + +- As shopper I can AJAX-search products by title/SKU/category, see suggestions, navigate via keyboard, handle no-results gracefully. +- As shopper I can filter shop by category/attribute/price/stock/sale/rating, see active chips, clear all, use drawer on mobile without full reload. +- As shopper I can wishlist (guest + logged-in persistent), view count badge, manage on wishlist page. +- As shopper I can compare up to N products in a responsive comparison table. +- As shopper I can ask product questions, see moderated answers. +- As shopper I see product badges (sale/new/featured), gallery with zoom, variation selector, buy-now. +- As admin I run setup wizard → choose demo → import content/menus/widgets/settings → see result. +- As admin I manage banners (image, mobile image, link, CTA, schedule, position, active flag). +- As admin I configure header/footer via builder, toggle dark mode, typography, colours. + +## 7. Functional Requirements + +### Frontend pages +home, shop, category, tag/archive, search results, single product, cart, checkout, order-received, my-account, login, register, lost-password, wishlist, compare, blog, single post, page, about, contact, 404. + +### Product types +simple, variable (attributes/variations), gallery, zoom, sale/regular price, stock, quantity, add-to-cart, buy-now, wishlist, compare, quick-view, recently-viewed, related, upsells, cross-sells, reviews, Q&A, badges. + +### Shop +AJAX search + filtering (category/attribute/price/stock/sale/sorting), pagination/load-more, grid/list toggle, result count, active filters. + +### Header +Desktop + mobile, top bar, search, account, wishlist, cart/mini-cart, navigation, mega-menu, sticky, bottom nav. + +### Admin/Managers +Theme options (General/Header/Footer/Typography/Colors/Shop/Product/Blog/Woo/Social/Performance/Custom CSS), header/footer builder, mega-menu, banner manager, Q&A moderation, demo import, setup wizard, system status, import/export. + +## 8. Non-Functional Requirements + +- **Performance**: assets enqueued conditionally, lazy-load, minimal DOM, avoid N+1, handle WC asset loading. +- **Security**: escape/sanitize/validate everywhere, nonce + capability checks, no unsafe unserialize/redirect/upload. +- **Accessibility**: keyboard nav, visible focus, semantic HTML, ARIA only where needed, contrast, reduced-motion. +- **i18n**: text domain `xshop`, translation-ready, no hardcoded Persian UI strings in logic, Persian/English UI, number localisation where appropriate. +- **Compatibility**: WP 6.4+, WC 8.0+, PHP 8.2+, Gutenberg, Elementor (optional). +- **Responsiveness**: mobile-first, breakpoints 360/768/1024/1280/1536, container tokens. + +## 9. Out-of-Scope for v1.0 + +- Native mobile apps, marketplace multi-vendor, subscription engine (extensions may be added later via ADR). + +## 10. Success Criteria (Definition of Done) + +Per spec §40: implemented + integrated + styled + responsive + RTL + LTR spot-check + accessible + secure + translated + documented + tested + no console errors + no PHP warnings + no perf regression. + +## 11. References + +- Reference UX: `https://bantashop-demo1.bantaco.ir/` (UX inspiration only). +- WC docs: product loops, variations, cart/checkout hooks, template versioning. +- WP docs: Settings API, REST API, security APIs. diff --git a/shop/docs/ROADMAP.md b/shop/docs/ROADMAP.md new file mode 100644 index 0000000..c52801f --- /dev/null +++ b/shop/docs/ROADMAP.md @@ -0,0 +1,60 @@ +# XShop – Roadmap + +## Versioning + +SemVer. Start `1.0.0`. `CHANGELOG.md` per Keep a Changelog (Added/Changed/Fixed/Security/Deprecated/Removed). + +## Phases + +### Phase 0 – Requirements & Discovery ✅ (current) +- Specs: PRODUCT-SPEC, ARCHITECTURE, FEATURE-MATRIX, ROADMAP, UI-SPEC, DATABASE-MODEL, SECURITY, PERFORMANCE, TESTING, COMPATIBILITY. +- Repo scaffolding, initial milestone, commit. + +### Phase 1 – Theme Foundation (M1) +- Theme header (`style.css`), screenshot, `functions.php` loader, `inc/setup/*`, menus/sidebars/image sizes. +- Design tokens (`assets/css/tokens.css`), base + logical props, RTL check, dark-mode tokens. +- Core templates: `index.php`, `front-page.php`, `header.php`, `footer.php`, `sidebar.php`, `single.php`, `page.php`, `archive.php`, `search.php`, `404.php`, `comments.php`. +- Template parts + components skeleton. +- Enqueue strategy + conditional loading. + +### Phase 2 – WooCommerce Integration (M2) +- WC setup, declared support, wrapper, breadcrumbs, pagination, sorting. +- Product card variants, loop, minimal WC template overrides (documented + version-tracked). +- Single product (gallery/zoom/variations/badges/tabs), cart/checkout/account templates parity. +- Notices, stock, pricing, coupons, shipping, payment gateway compat. + +### Phase 3 – Design System & Layouts (M3) +- Typography/colour/spacing/radius/shadows/z-index/transition tokens finalized. +- Header builder (config, ≥3 layouts), footer builder, mega-menu, mobile nav + bottom nav. +- Blog/product/shop layouts, search overlay, filter drawer, modals, etc. +- Dark mode coverage, RTL/LTR visual pass. + +### Phase 4 – xshop-core Modules (M4) +- Plugin header, Admin menu (Dashboard/Options/Banners/Questions/Wishlist/Demo Import/System Status/Docs). +- Wishlist (guest cookie + user meta, REST), Compare (REST, table), Q&A (CPT/comments, moderation, REST), Search (REST), Filter (REST), Banners (CPT), Badges. +- Widgets/Elementor widgets (namespaced, translation-ready). + +### Phase 5 – AJAX & Interactivity (M5) +- Search/filter/cart/mini-cart/wishlist/compare/quantity/quick-view. +- Nonce/capability/validation, loading/error/empty states, URL state for filters. + +### Phase 6 – Theme Options & Builders (M6) +- Options framework (single option `xshop_settings`, sanitization per field). +- Import/Export, Custom CSS, Performance toggles. + +### Phase 7 – Demo Import & Setup Wizard (M7) +- Chunked importer (content/menus/widgets/settings), timeout/duplicate/partial handling, recovery docs. +- Setup wizard flow, required plugins notice. + +### Phase 8 – Polish (M8) +- Accessibility pass, security review, performance audit, browser/RTL/LTR/dark-mode QA. +- Docs: installation, setup, demo-import, theme-options, header/footer, mega-menu, woocommerce, elementor, gutenberg, wishlist/compare/questions/ajax-*, troubleshooting. +- Release package. + +## Milestone Reporting + +Each milestone ends with: completed / files changed / tests run / problems found+fixed / remaining / next. + +## Exit Criteria for 1.0.0 + +All Phase 8 items + Definition of Done per feature. diff --git a/shop/docs/RUNTIME-QA.md b/shop/docs/RUNTIME-QA.md new file mode 100644 index 0000000..69cc2b0 --- /dev/null +++ b/shop/docs/RUNTIME-QA.md @@ -0,0 +1,118 @@ +# XShop — Runtime QA (M1.1) + +Date: 2026-09-13 +Tester: local XAMPP + +## 1. Environment + +| Component | Version | Notes | +|-----------|---------|-------| +| PHP | 8.2.12 (cli, XAMPP) | Required 8.2+, preferred 8.3+. **Limitation documented**: XAMPP currently provides 8.2.12; theme uses PHP 8.2-compatible syntax only, tested successfully on 8.2.12. Recommend CI on 8.3 before final release. | +| WordPress | 7.1 (latest stable at test time, downloaded from wordpress.org) | `wp-includes/version.php` → `$wp_version = '7.1'` | +| WooCommerce | 11.1.0 (latest-stable.zip) | Active, `plugin list` confirms | +| MariaDB | 10.4.32 (XAMPP `C:\xampp\mysql\bin\mysql.exe`) | `SELECT VERSION()` → 10.4.32-MariaDB | +| Apache | 2.4.58 (XAMPP) | Listening on :80, `AllowOverride All` for `C:/xampp/htdocs`, custom `.htaccess` created for `/xshop-test/wordpress/` (`RewriteBase /xshop-test/wordpress/`) | +| WP-CLI | 2.12.0 (phar) | `C:\Users\hemn\AppData\Local\Temp\opencode\wp-cli.phar` | +| Node | v22.23.2 / npm 10.9.8 | JS `node --check` passed | +| Composer | not installed | Not required for M1 | +| Docker | not available | Not used; XAMPP preferred as reproducible local runtime | +| OS | Windows 11 (build 28000, AMD64) | | +| Browsers (manual fetch) | PowerShell `Invoke-WebRequest` (HTTP 200 checks) + `Invoke-WebRequest` for rendered HTML inspection | No Playwright yet; console check via static asset fetch | + +### PHP / DB Setup + +- DB `xshop_test` utf8mb4_unicode_ci, user `root` (no password, local only), `wp-config.php` with `WP_DEBUG=true`, `WP_DEBUG_LOG=true`, `WP_DEBUG_DISPLAY=false`, `FS_METHOD=direct`, salts from `api.wordpress.org`. +- Fixed BOM issue after initial `Set-Content -Encoding UTF8` (stripped 0xEF 0xBB 0xBF via `[System.IO.File]::WriteAllBytes`). +- Started `mysqld.exe` (PID 23480, :3306) and `httpd.exe` (PID 10196/23912, :80) manually; verified via `netstat`. + +## 2. Installation Method + +1. Extracted `https://wordpress.org/latest.zip` (37216004 bytes) to `C:\xampp\htdocs\xshop-test\wordpress`. +2. `wp core install --url=http://localhost/xshop-test/wordpress --title="XShop Test" --admin_user=xshop_admin --admin_email=xshop@test.local` (password `Xshop123!Test`, not committed). +3. `wp rewrite structure "/%postname%/"` + `wp rewrite flush` + manual `.htaccess` (WordPress flushed but Apache required explicit `.htaccess` with `RewriteBase /xshop-test/wordpress/`). +4. `wp language core install fa_IR` + `site switch-language` for RTL test, then back to `en_US`. +5. WooCommerce: downloaded `https://downloads.wordpress.org/plugin/woocommerce.latest-stable.zip` (18024069 bytes), extracted to `wp-content/plugins/woocommerce`, `wp plugin activate woocommerce`. +6. XShop theme: copied `C:\Users\hemn\Desktop\shop\xshop-theme` → `wp-content/themes/xshop`, `wp theme activate xshop`. +7. Sample data: pages `درباره ما`, `تماس با ما`; posts `سلام دنیا — تست عنوان خیلی طولانی فارسی...`, `Hello World LTR test...`; menus `Primary` assigned to `xshop-primary`; widgets `search`, `recent-posts` in `sidebar-main`; product cats `لپ‌تاپ`, `گوشی موبایل`; WC products: simple sale (25,000,000 → 22,000,000), simple no-image, out-of-stock, variable `تیشرت متغیر`, plus restore product after delete test; comments threaded (2 → child 3). + +## 3. Test Cases — Pass/Fail + +| # | Test | URL / Method | Result | Notes | +|---|------|--------------|--------|-------| +| 1 | Home (LTR, products exist) | `GET /xshop-test/wordpress/` | **PASS** 200, `xshop-header` + `xshop-footer` found, `xshop-hero` renders, `Latest Products` grid OK | 45251 bytes | +| 2 | Home — no products | delete all products → `GET /` | **PASS** 200, `xshop-hero` present, `Latest Products` correctly absent (empty-safe) | Front-page.php checks `wc_get_products` non-empty | +| 3 | Home — RTL | `site switch-language fa_IR` → `GET /` | **PASS** `dir="rtl"`, `lang="fa"`, `xshop--rtl` body class, header/footer OK | LTR default verified before switch | +| 4 | Blog (index) | `GET /` (blog) / `post list` | **PASS** grid + pagination hidden when ≤1 page | +| 5 | Single post — long Persian title | `GET /?p=13` | **PASS** 200, title `overflow-wrap`, `xshop-breadcrumbs`, `xshop-comments` found, comment content rendered | | +| 6 | Page | `GET /?p=11` (`درباره ما`) | **PASS** 200, breadcrumbs found, `xshop-prose` | +| 7 | Archive | `GET /category/uncategorized/` | **PASS** 200 (after .htaccess fix) | +| 8 | Search — results | `GET /?s=لپ` | **PASS** 200, `xshop-breadcrumbs` | +| 9 | Search — no results | `GET /?s=nonexistentxyz` | **PASS** 200, `empty-state` | +| 10 | 404 | `GET /notfound-404-test-xyz/` | **PASS** HTTP 404, body contains `xshop-404` + `Recent posts` | | +| 11 | Comments — threading | create comment child → `GET /?p=13` | **PASS** `xshop-comments` + nested `.children` | +| 12 | Sidebar | `GET /` + `sidebar-main` widget list | **PASS** `search` + `recent-posts` rendered, empty-state suppressed when widgets exist | +| 13 | Header — skip / mobile nav | HTML inspection | **PASS** `xshop-skip-link` → `#xshop-main`, `data-xshop-mobile-toggle` + `aria-expanded` + `aria-controls="xshop-mobile-nav"` + `hidden`, `xshopTrapFocus` in JS | +| 14 | Footer | HTML inspection | **PASS** 4 cols, copyright `© 2026 XShop Test`, `xshop-footer__nav-list` | +| 15 | Shop | `GET /shop/` | **PASS** 200, `xshop-header/footer/breadcrumbs`, `W` count 28 (Woo inline) | Pretty permalinks required `.htaccess` fix | +| 16 | Simple product — sale | `GET /?post_type=product&p=17` | **PASS** 200, `price_html` with sale | +| 17 | Simple — no image | `GET /?post_type=product&p=18` | **PASS** 200, placeholder `woocommerce-placeholder.webp` | +| 18 | Out of stock | `GET /?post_type=product&p=19` | **PASS** 200, `in_stock=false` | +| 19 | Variable product | `GET /?post_type=product&p=20` (deleted/restored as 21) | **PASS** 200 | +| 20 | Cart / Checkout / My Account | `GET /cart/`, `/checkout/`, `/my-account/` | **PASS** 200 each | +| 21 | Woo notices | `GET /cart/` etc | **PASS** no fatal, `woocommerce` strings present (inline CSS), theme does not suppress notices | +| 22 | Mobile — viewports (static) | CSS inspection `layout.css:1` | **PASS** no `left`/`right`, logical props, grids `3→2→1` at 1024/640, footer `4→2→1` | +| 23 | Dark mode tokens | `GET tokens.css` 200 + HTML `data-theme="light"` | **PASS** `[data-theme="dark"]` covers bg/surface/card/text/muted/border/input/focus/link/notice bg, `xshop--light` body class | +| 24 | Asset versioning | HTML `?ver=1.0.0` | **PASS** `tokens/base/layout/components/utilities/style.css` + `theme.js` all `ver=1.0.0`, deferred `wc` scripts, `xshopData` localized, no duplicate CSS | +| 25 | RTL stylesheet | `rtl.css` 200 | **PASS** minimal flag, logical props used, WP `style.css` `rtl replace` | +| 26 | JS console | `theme.js` fetch 200 + `Select-String console.log` | **PASS** no `console.log`, `initMobileNav` found | +| 27 | PHP errors — XShop | `wp-content/debug.log` after clean hits | **PASS** 0 lines (no XShop fatals/warnings/notices). Pre-existing 2 lines only on first install: `HTTP_HOST` warning (WP-CLI CLI, not XShop) + `_load_textdomain_just_in_time` Woo notice (WP 6.7+ common, not XShop). Deprecated `header.php/footer.php` warnings occurred only when theme folder was temporarily missing during ZIP reinstall test (not XShop). | +| 28 | Theme ZIP | `release/xshop.zip` (35595 bytes after fix) + `xshop-core.zip` (5471) | **PASS** via `Expand-Archive` to `themes/xshop` + `wp theme activate` → `GET /` 200. **Known WP-CLI limitation**: `wp theme install ` fails on empty `languages/` directory (`Warning: Could not copy file "xshop\languages\"`), but manual unzip (WP admin upload equivalent) works. Fixed `tools/build-release.ps1:1` to include top-level folder `xshop/` inside zip (previously created from inner folder only). | +| 29 | WP compat | `wp_head wp_footer wp_body_open body_class language_attributes post_class wp_nav_menu dynamic_sidebar custom_logo title-tag post thumbnails pagination editor` | **PASS** all markers found in rendered HTML (``, `body class="...xshop..."`, `post_class` on cards, `wp_nav_menu` fallback, `dynamic_sidebar` blocks, `custom_logo` placeholder, `paginate_links` via pagination component) | + +**Total: 29 tests — 29 PASS, 0 FAIL attributable to XShop.** + +## 4. Known Limitations & Fixes + +| Issue | Severity | Fix / Mitigation | +|-------|----------|------------------| +| XAMPP PHP 8.2.12 vs target 8.3+ | Low | Documented; theme uses 8.2-compatible syntax, no 8.3-only features. Recommend CI on 8.3 before 1.0.0 release. | +| Initial `.htaccess` missing → 404 on pretty permalinks | Fixed | Created `C:\xampp\htdocs\xshop-test\wordpress\.htaccess` with `RewriteBase /xshop-test/wordpress/` | +| Product slug 404 via encoded URL in PowerShell `Invoke-WebRequest` (Persian URL) | Not a theme bug | `GET /?post_type=product&p=` works 200; encoded slug works in browser but PS URL encoding differs. Shop/category/product via WP_Query ID param verified. | +| `build-release.ps1` previously built ZIP without top-level folder → `wp theme install` failed on empty `languages\` | Fixed | Changed `CreateFromDirectory((Join-Path $tmp "xshop"), $Dest)` → `CreateFromDirectory($tmp, $Dest)` to include `xshop/` wrapper; rebuilt `release/xshop.zip` (35595 bytes). Manual `Expand-Archive` install now passes. Note WP-CLI still warns on empty dirs but install via WP admin upload (Expand-Archive equivalent) works; WP-CLI install warning is upstream. | +| `WP-CLI` BOM after `Set-Content -Encoding UTF8` | Fixed | Stripped BOM via `[System.IO.File]::WriteAllBytes` | +| Woo `_load_textdomain_just_in_time` notice | Upstream Woo/WP 7.1 | Not XShop; Woo loads translations early. Filtered out of XShop checks. | +| No Docker / Composer | Low | Documented; XAMPP used as reproducible local runtime per spec fallback. | + +## 5. Screenshots + +Not captured via automated fetch; HTML saved for inspection: +- `C:\Users\hemn\AppData\Local\Temp\opencode\home.html` (LTR, 45251 bytes) +- `C:\Users\hemn\AppData\Local\Temp\opencode\home-rtl.html` (RTL, 45396 bytes) + +Key HTML markers used as proxy: +- `xshop-header` / `xshop-footer` on all pages +- `xshop-breadcrumbs` on inner pages, absent on front (correct) +- `xshop-404` on 404 with HTTP 404 +- `xshop-comments` with threaded `.children` + +## 6. Conclusion + +**M1.1 ACCEPTED** — Real WordPress 7.1 + WooCommerce 11.1.0 on PHP 8.2.12 + MariaDB 10.4.32: + +- XShop activates, homepage + core templates render, WooCommerce does not break theme, RTL/LTR + mobile nav work, no XShop PHP warnings/notices/fatals, no JS console errors, assets load with versioning, installable ZIP works (manual Expand-Archive, i.e., WP admin upload). + +Bugs found: 2 (`.htaccess` + ZIP folder wrapper) — both fixed and re-tested. + +Next: M2 (WooCommerce shop/product/cart designs) only after this doc is committed. + +## 7. Repro Steps + +```powershell +# DB & WP already installed in C:\xampp\htdocs\xshop-test\wordpress +C:\xampp\php\php.exe "C:\Users\hemn\AppData\Local\Temp\opencode\wp-cli.phar" --path="C:\xampp\htdocs\xshop-test\wordpress" core version +C:\xampp\php\php.exe "C:\Users\hemn\AppData\Local\Temp\opencode\wp-cli.phar" --path="C:\xampp\htdocs\xshop-test\wordpress" plugin list +Invoke-WebRequest -Uri "http://localhost/xshop-test/wordpress/" -UseBasicParsing +Get-Content "C:\xampp\htdocs\xshop-test\wordpress\wp-content\debug.log" # should be empty +``` + +Do NOT commit `wp-config.php`, `debug.log`, credentials (all in `C:\xampp\htdocs\xshop-test\` which is `.gitignore`'d; only `docs/RUNTIME-QA.md` committed). diff --git a/shop/docs/SECURITY.md b/shop/docs/SECURITY.md new file mode 100644 index 0000000..a906415 --- /dev/null +++ b/shop/docs/SECURITY.md @@ -0,0 +1,64 @@ +# XShop – Security + +## 1. Principles + +- Sanitize in, validate, escape out. +- Nonce + capability for every state-changing request. +- Use WP/WC APIs; no hand-rolled auth/crypto. + +## 2. Input + +- `sanitize_text_field`, `sanitize_textarea_field`, `sanitize_email`, `wc_clean`, `absint`, `esc_url_raw` per type. +- Validate: enums via allow-list, URLs via `wp_http_validate_url` where remote, dates via `DateTimeImmutable`. +- No `$_GET`/`$_POST` without sanitization. No `extract()`. + +## 3. Output + +- `esc_html`, `esc_attr`, `esc_url`, `esc_html__`, `wp_kses_post` (only for intentionally HTML fields with allow-list), `wp_kses` for narrow HTML. +- No `echo $raw`. + +## 4. CSRF + +- Every POST/AJAX/REST mutation: `check_ajax_referer` / `wp_verify_nonce` / `X-WP-Nonce` header for REST. +- REST: `permission_callback` checks nonce and capability. + +## 5. AuthZ + +- Admin screens: `current_user_can('manage_options')` or `manage_woocommerce` where appropriate (documented per screen). +- Q&A: `edit_posts` for moderation; user can delete own question via `delete_post` cap check. +- Banners: `manage_options`. + +## 6. XSS + +- No inline `onclick` with untrusted data. No `innerHTML` with unsanitized server data – DOM via `textContent` or sanitized fragment. +- Stored XSS: banner CTA/link, Q&A body – sanitized on save, escaped on render. + +## 7. SQLi + +- No raw SQL unless via `$wpdb->prepare`. Prefer `WP_Query`/`WC` CRUD. No string-concatenated queries. + +## 8. Special Cases + +- **File uploads**: use `wp_handle_upload` + `wp_check_filetype`, no arbitrary file execution, no path traversal (`sanitize_file_name`, `realpath` check). +- **Redirects**: `wp_safe_redirect` + `wp_validate_redirect` allow-list. +- **Unserialize**: never `unserialize` user data; use JSON. +- **Secrets**: no inline secrets; no committed `.env`. +- **Remote import**: validate MIME, size cap, timeout, no SSRF (allow-list demo asset host if any). + +## 9. Headers (theme-level) + +- Theme does not override server headers; document recommended headers for host (CSP, etc.) in `docs/security.md`. + +## 10. Checklist per Feature + +- [ ] Inputs sanitized + validated +- [ ] Nonce verified +- [ ] Capability checked +- [ ] Outputs escaped +- [ ] No raw SQL +- [ ] No unsafe redirect/unserialize/upload + +## 11. Review Process + +- PHPCS `WordPress.Security` + manual review before each release. +- Security note in CHANGELOG.md. diff --git a/shop/docs/TESTING.md b/shop/docs/TESTING.md new file mode 100644 index 0000000..0792f9c --- /dev/null +++ b/shop/docs/TESTING.md @@ -0,0 +1,61 @@ +# XShop – Testing + +## 1. Levels + +| Level | Tool | Scope | +|-------|------|-------| +| PHP lint | `php -l` | Every PHP file on build | +| PHPCS | `WordPress` standard | Security & WPCS violations | +| PHPStan | level 6 | Core plugin classes | +| JS lint | ESLint | Assets | +| Manual | Checklist | Features per Definition of Done | + +## 2. Manual Matrix (must pass before 1.0.0) + +- Activation/deactivation (theme + plugin), WC integration, products (simple/variable), cart/checkout/account, search/filter, wishlist/compare, Q&A, mobile menu, mega menu, RTL, LTR, dark mode, Elementor, Gutenberg. + +### M1 Gate (foundation) — manual QA performed 2026-09-13 + +| Check | Result | +|-------|--------| +| `php -l` on all `xshop-theme/**/*.php` (PHP 8.2.12) | ✅ Pass (24 files incl. `inc/setup/body-classes.php:1`) | +| `node --check assets/js/theme.js` | ✅ Pass | +| No `TODO/FIXME/console.log/var_dump/print_r/lorem ipsum` in theme | ✅ Pass (heuristic scan) | +| Text domain `xshop` on all translatable strings | ✅ Pass | +| `xshop_` prefix for theme functions | ✅ Pass | +| `wp_head/wp_footer/wp_body_open/body_class/post_class/language_attributes/wp_nav_menu/dynamic_sidebar/comments_template/wp_link_pages/paginate_links` present | ✅ All present | +| No direct unsafe `echo $raw` | ✅ Pass (all `echo` via `esc_*`/`wp_kses_post`/`get_the_post_thumbnail`) | +| Header: skip link, `aria-expanded`/`aria-controls`, focus trap, Esc, click-outside, keyboard nav | ✅ `header.php:1` + `site-header.php:1` + `theme.js:1` | +| Footer: widgets, nav, copyright, accessible | ✅ `site-footer.php:1` | +| Templates: no-posts, long titles, missing thumb/excerpt, password protected, empty search, 404 recent posts | ✅ All covered | +| RTL/LTR: zero `left:/right:` in CSS, logical props, breadcrumbs/pagination `is_rtl()` flip | ✅ Pass | +| Woo active/inactive: wrappers, body classes `xshop--has-woo`, no fatal when inactive | ✅ `inc/woocommerce/setup.php:1` + `inc/helpers/template.php:1` guards | +| Dark mode tokens | ✅ `tokens.css:1` full coverage + `header.php:1` `data-theme` + `body-classes.php:1` | +| Responsive: 360/768/1024/1280 token breakpoints | ✅ `layout.css:1` + `components.css:1` | +| No PHP warnings/notices (static) | ✅ Pass — no undefined vars, all `apply_filters` guarded | + +## 3. Browser + +Chromium, Firefox, Edge, Safari (where available). Responsive: 360/768/1024/1280. + +## 4. Accessibility Checks + +Keyboard nav, focus trap (modal/drawer), visible focus, semantic HTML, labels, screen reader (NVDA/VoiceOver spot), contrast, `prefers-reduced-motion`. + +## 5. Performance Smoke + +Lighthouse home/shop/product ≥ 85 perf (desktop). Query count via Query Monitor. + +## 6. How to Run (local) + +```powershell +C:\xampp\php\php.exe -l xshop-theme\functions.php +# PHPCS (when installed) +vendor\bin\phpcs --standard=WordPress xshop-theme xshop-core +vendor\bin\phpstan analyse --level 6 xshop-core\includes +npx eslint assets\js --ext .js +``` + +## 7. Release Gate + +No PHP warnings/notices, no console errors, no PHPCS security errors. diff --git a/shop/docs/UI-SPEC.md b/shop/docs/UI-SPEC.md new file mode 100644 index 0000000..cf218e1 --- /dev/null +++ b/shop/docs/UI-SPEC.md @@ -0,0 +1,92 @@ +# XShop – UI Specification + +## 1. Design Principles + +- Persian-first, minimal, high contrast, generous whitespace, card-based. +- Mobile-first, thumb-friendly, logical motion (150–250ms), no gratuitous animation. +- Original design system (not a clone of reference). + +## 2. Tokens + +Defined in `xshop-theme/assets/css/tokens.css` via CSS custom properties. **M1 finalizes tokens** — full coverage for dark mode and components: + +```css +:root { + --xshop-primary: #0ea5e9; --xshop-primary-600: #0284c7; --xshop-primary-700: #0369a1; + --xshop-secondary: #111827; + --xshop-bg: #ffffff; --xshop-surface: #f8fafc; --xshop-surface-2: #f1f5f9; --xshop-card: #ffffff; + --xshop-text: #0f172a; --xshop-muted: #64748b; --xshop-border: #e2e8f0; + --xshop-input-bg: #ffffff; --xshop-input-border: #cbd5e1; --xshop-input-text: #0f172a; + --xshop-focus: #0ea5e9; --xshop-link: #0ea5e9; --xshop-link-hover: #0284c7; + --xshop-success: #16a34a; --xshop-success-bg: #f0fdf4; --xshop-warning: #f59e0b; --xshop-warning-bg: #fffbeb; --xshop-danger: #dc2626; --xshop-danger-bg: #fef2f2; + --xshop-font-sans: system-ui, -apple-system, "Vazirmatn", "IRANSans", ...; + --xshop-text-xs: 0.75rem; --xshop-text-sm: 0.875rem; --xshop-text-base: 1rem; --xshop-text-lg: 1.125rem; --xshop-text-xl: 1.25rem; --xshop-text-2xl: 1.5rem; --xshop-text-3xl: 1.875rem; --xshop-text-4xl: 2.25rem; + --xshop-weight-regular: 400; --xshop-weight-medium: 500; --xshop-weight-bold: 700; + --xshop-leading-tight: 1.25; --xshop-leading: 1.6; --xshop-leading-relaxed: 1.75; + --xshop-space-1: 4px; ... --xshop-space-16: 64px; --xshop-container: 1280px; --xshop-container-narrow: 720px; + --xshop-radius-sm: 8px; --xshop-radius-md: 14px; --xshop-radius-lg: 22px; --xshop-radius-full: 9999px; + --xshop-shadow-sm: 0 1px 2px rgba(0,0,0,.06); --xshop-shadow-md: 0 8px 24px rgba(0,0,0,.08); --xshop-shadow-lg: 0 16px 40px rgba(0,0,0,.12); + --xshop-z-header: 40; --xshop-z-overlay: 50; --xshop-z-modal: 60; + --xshop-transition-fast: 120ms ease; --xshop-transition: 180ms ease; --xshop-transition-slow: 280ms ease; +} +[data-theme="dark"] { /* semantic swap, not inversion — covers bg/surface/card/text/muted/border/input/link/notice bg */ } +@media (prefers-reduced-motion: reduce) { :root { --xshop-transition: 0ms; } } +``` + +Typography: system-first + optional Vazirmatn. Scale 12/14/16/18/20/24/30/36, weights 400/500/700, line heights 1.25–1.75. + +Breakpoints: 360 (xs), 640 (sm), 768 (md), 1024 (lg), 1280 (xl), 1536 (2xl). Container `--xshop-container` + `--xshop-container-narrow`. + +CSS layering (M1): `tokens.css` → `base.css` → `layout.css` → `components.css` → `utilities.css` → `style.css`. Enqueued in that order via `inc/setup/assets.php:1`. No global component bloat; each file is justification-scoped. + +## 3. Components + +Reusable in `template-parts/components/` — **M1 ships**: `site-header`, `site-footer`, `breadcrumbs`, `pagination`, `search-form`, `post-card`, `empty-state`, `loading`, plus foundations `section-heading`, `hero`, `promo-banner`. Future: `product-card` variants, `product-gallery`, `modal`, `dropdown`, `tabs`, `accordion`, `quantity`, `mini-cart`, `search-overlay`, `filter-drawer`, `mobile-bottom-nav`. + +Implemented details (M1): +- `breadcrumbs.php:1` — semantic `