# Wow Extensions for WooCommerce — AI Prompt Reference

> Use this document as context when working on the plugin with an AI coding assistant.
> Last audited: v1.0.0

---

## 1. What This Plugin Does

A modular WooCommerce add-on framework. The core provides a dashboard where store owners toggle features on/off; each feature is a self-contained **extension** that registers itself via filters. The only shipping extension so far is **Role Based Pricing** (set per-role prices, discounts/markups, hide price/add-to-cart by role).

- **Slug:** `wow-extensions-for-woocommerce`
- **Text domain:** `wow-extensions-for-woocommerce`
- **Min requirements:** WP 5.8, PHP 7.4, WC 5.0
- **License:** GPL-2.0-or-later

---

## 2. Directory Layout

```
wow-extensions-for-woocommerce/
├── wow-extensions-for-woocommerce.php   ← main entry (plugin headers, constants, bootstrap)
├── package.json                            ← npm build: clean-css-cli + terser + chokidar
├── .gitignore
├── README.md
├── PROMPT.md                               ← this file
│
├── includes/                               ← core classes
│   ├── class-helper.php                    ← Wowexfow_Plugin_Helper (static utilities)
│   ├── class-admin.php                     ← Wowexfow_Plugin_Admin (menus, settings UI, save handlers)
│   └── class-extensions-manager.php        ← Wowexfow_Plugin_Manager (extension loader)
│
├── extensions/                             ← one subfolder per extension
│   └── role-based-pricing/
│       ├── class-role-based-pricing.php    ← entry (loads deps, inits admin/frontend/dashboard)
│       ├── includes/
│       │   ├── class-role-based-pricing-dashboard-settings.php  ← settings UI & sanitization
│       │   └── class-role-based-pricing-frontend.php            ← price/visibility filters
│       ├── wow-includes/                  ← legacy WOW helpers (dependency check, WC compat)
│       │   ├── wow-dependencies.php
│       │   └── wow-functions.php
│       └── resources/css/bootstrap.css     ← unused/leftover
│
├── src/                                    ← source assets (served in dev mode)
│   ├── css/admin.css
│   └── js/admin.js
│
├── assets/                                 ← production assets (built, gitignored)
│   ├── css/.gitkeep
│   ├── js/.gitkeep
│   ├── images/icon-128x128.jpg
│   └── vendor/select2/                     ← bundled Select2 4.0.13
│       ├── css/select2.min.css
│       └── js/select2.full.min.js
│
└── languages/
    └── index.php                           ← "silence is golden" stub
```

---

## 3. Architecture & Boot Sequence

```
wow-extensions-for-woocommerce.php
  └─ wow_extensions()                          // global function, boots singleton
     └─ Wowexfow_Plugin::instance()
        ├─ check_woocommerce()                    // admin notice if WC missing
        ├─ includes()                             // require class-helper, class-admin, class-extensions-manager
        └─ init_hooks()
           ├─ plugins_loaded → load_textdomain()
           ├─ before_woocommerce_init → declare HPOS + blocks compat
           ├─ init → Wowexfow_Plugin_Admin::instance()      (admin only)
           │         Wowexfow_Plugin_Manager::instance()
           │            ├─ load_extensions()                   // glob extensions/*/class-*.php, require_once each
           │            ├─ filter: wowexfow_available_features → register_features()
           │            └─ init (pri 20) → init_extensions()   // instantiate enabled extension classes
           ├─ register_activation_hook → activate()            // default options, flush rewrite
           └─ register_deactivation_hook → deactivate()
```

**Pattern:** All core and extension classes use the **singleton** pattern (`private __construct`, static `$instance`, `::instance()`). Extensions are plain classes instantiated by the manager when enabled.

**No namespaces.** Everything is in the global PHP namespace with an `Wowexfow_Plugin_*` prefix (core) or `Wow_*` prefix (legacy WOW helpers).

---

## 4. Class Reference

| Class | File | Role |
|-------|------|------|
| `Wowexfow_Plugin` | `wow-extensions-for-woocommerce.php` | Main singleton. Constants, WC check, boot. |
| `Wowexfow_Plugin_Helper` | `includes/class-helper.php` | Static utility: `is_feature_enabled()`, `get_available_features()`, `is_dev_mode()`, `get_asset_url()`, `get_asset_path()`. |
| `Wowexfow_Plugin_Admin` | `includes/class-admin.php` | Admin menu (Home + Settings), enqueue scripts/styles, save handler (`maybe_save_dashboard`), render dashboard with vertical tabs, feature toggles, inline settings panels. |
| `Wowexfow_Plugin_Manager` | `includes/class-extensions-manager.php` | Discovers extension files via `glob()`, collects feature info, instantiates enabled extensions on `init` priority 20. |
| `Wowexfow_Plugin_Role_Based_Pricing` | `extensions/role-based-pricing/class-role-based-pricing.php` | Extension entry. Loads WOW deps (local or from sibling plugin), inits dashboard settings + frontend. |
| `Wowexfow_Plugin_Role_Based_Pricing_Dashboard_Settings` | `extensions/role-based-pricing/includes/class-role-based-pricing-dashboard-settings.php` | Renders settings form via filter, sanitizes + saves to `wowexfow_role_pricing_settings` option. |
| `Wowexfow_Plugin_Role_Based_Pricing_Frontend` | `extensions/role-based-pricing/includes/class-role-based-pricing-frontend.php` | WC price filters, hide price HTML, hide add-to-cart for selected roles. Reads product meta (`_role_price_{role}`, `_role_sale_price_{role}`) and applies default adjustments (% or fixed). |
| `Wow_Dependencies` | `extensions/role-based-pricing/wow-includes/wow-dependencies.php` | Legacy: checks WC is active. |

---

## 5. Hooks & Filters (Custom)

### Filters

| Filter | Location | Purpose |
|--------|----------|---------|
| `wowexfow_registered_extensions` | Manager + each extension | Array of `slug => class_name`. Extensions add themselves here. |
| `wowexfow_available_features` | Helper + Manager | Array of `slug => ['title','description']`. Drives the dashboard UI. |
| `wowexfow_feature_settings_content` | Admin (`get_feature_settings_content`) | Extensions return HTML for their inline settings panel. Receives `($content, $feature_slug)`. |
| `wowexfow_role_price_from_meta` | Frontend | Fallback filter for role price when no meta found. Receives `(null, $product, $price_type, $role)`. |

### Actions

The plugin relies on standard WordPress/WooCommerce actions (`init`, `admin_init`, `admin_menu`, `admin_enqueue_scripts`, `plugins_loaded`, `before_woocommerce_init`, `admin_post_*`, WC price/template hooks). No custom actions are fired.

---

## 6. Database Options

| Option Key | Type | Contents |
|------------|------|----------|
| `wow_extensions_features` | `array` | `['role_based_pricing' => 'yes'\|'no', ...]` — per-feature toggle state. |
| `wowexfow_role_pricing_settings` | `array` | `enabled_roles`, `default_type` (percentage\|fixed), `default_value`, `apply_to` (regular\|sale\|both), `hide_price_roles`, `hide_add_to_cart_roles`. |

### Product Meta Keys (Role Based Pricing)

| Meta Key Pattern | Example | Purpose |
|------------------|---------|---------|
| `_role_price_{role}` | `_role_price_wholesale` | Per-product regular price for a role. |
| `_role_sale_price_{role}` | `_role_sale_price_wholesale` | Per-product sale price for a role. |
| `_wow_regular_price_{role}` | `_wow_regular_price_wholesale` | Legacy WOW alt key (also checked as fallback). |
| `_wow_sale_price_{role}` | `_wow_sale_price_wholesale` | Legacy WOW alt key (fallback). |

---

## 7. Extension System — How to Add a New Extension

1. Create `extensions/your-slug/class-your-slug.php`.
2. Register via the `wowexfow_registered_extensions` filter:

```php
add_filter( 'wowexfow_registered_extensions', function( $extensions ) {
    $extensions['your_slug'] = 'Wowexfow_Plugin_Your_Slug';
    return $extensions;
});
```

3. Implement `get_feature_info()` returning `['title' => '...', 'description' => '...']`.
4. The class is auto-instantiated by the manager when the feature is toggled on.
5. For inline dashboard settings, hook into `wowexfow_feature_settings_content`:

```php
add_filter( 'wowexfow_feature_settings_content', function( $content, $slug ) {
    if ( 'your_slug' !== $slug ) return $content;
    ob_start();
    // ... render HTML (no <form> tag — fields are inside the main dashboard form) ...
    return ob_get_clean();
}, 10, 2 );
```

6. The manager discovers files via `glob( extensions/*/class-*.php )` — the entry file **must** match that pattern.
7. Add a default toggle state in the `activate()` method's `$default_features` array.
8. Add an SVG icon in `Wowexfow_Plugin_Admin::get_feature_icon()` keyed by feature slug.

---

## 8. Build Pipeline

```bash
npm run build        # clean-css + terser → assets/css/admin.css, assets/js/admin.js
npm run dev          # watch mode (chokidar)
```

- Source: `src/css/admin.css`, `src/js/admin.js`
- Output: `assets/css/admin.css`, `assets/js/admin.js` (gitignored)
- Dev mode: When `WOWEXFOW_DEV_MODE` (or `WP_DEBUG`) is true, assets are served from `src/`; otherwise from `assets/`.
- Dependencies: `clean-css-cli`, `terser`, `chokidar-cli` (devDependencies).
- The `package.json` also has a large `dependencies` block (npm artifacts); only `devDependencies` matter for the build.

---

## 9. Admin UI Architecture

- **Two admin pages** under a top-level "Wow Extensions" menu:
  - **Home** (`wow-extensions`) — branding/welcome page.
  - **Settings** (`wow-extensions-settings`) — feature management dashboard.
- **Settings page layout:** vertical sidebar tabs (one per extension) + right-side panel with toggle switch and inline settings.
- **Scripts/styles** only enqueued on the Settings page (`wow-extensions_page_wow-extensions-settings` hook).
- **Select2** (bundled v4.0.13) is used for multi-select role pickers.
- **Form save flow:** Single `<form>` POSTs to the same page. `maybe_save_dashboard()` on `admin_init` (priority 3) handles both feature toggles and RBP settings, then redirects with `?updated=1` or `?updated=rbp`.
- **JS behavior:** Tab switching, toggle label update, settings panel expand/collapse, Select2 init, "no changes" guard on submit.

---

## 10. Frontend Price Logic (Role Based Pricing)

Priority chain for determining a product's price:

1. **Per-product role meta** — checks `_role_price_{role}` / `_role_sale_price_{role}` (and WOW fallback keys) for each of the user's matching enabled roles.
2. **Default adjustment** — if no per-product role price exists and the user has an enabled role, applies the global `default_value` as either percentage or fixed discount/markup.
3. **Original price** — falls through unchanged.

Visibility rules:
- **Hide price:** Roles in `hide_price_roles` get empty `woocommerce_get_price_html`.
- **Hide add-to-cart:** Roles in `hide_add_to_cart_roles` → `woocommerce_is_purchasable` returns false + template actions removed.

Frontend filters only run on non-admin pages (skips `is_admin() && !wp_doing_ajax()`).

---

## 11. WOW Legacy Integration

The Role Based Pricing extension was migrated from a standalone plugin (`wow-woocommerce-role-based-pricing`). Key points:

- `load_dependencies()` tries to load `Wow_Price_Discount_Admin` and `Wow_Admin_Notice` from the local `includes/` first, then falls back to the standalone plugin directory.
- Those admin files (`wow-price-discount-admin.php`, `wow-class-admin-notice.php`) are **not shipped** in this repo — product-level meta boxes only work if the WOW plugin is also installed or those files are copied in.
- `wow-functions.php` provides polyfills for very old WC versions (`wc_get_price_including_tax`, `wc_get_price_to_display`, etc.). These are wrapped in `function_exists()` checks.
- The WC settings tab from WOW has been intentionally removed; settings now live in the Wow Extensions dashboard.

---

## 12. Coding Conventions

| Convention | Details |
|------------|---------|
| **PHP version** | 7.4+ (no union types, no enums, no named args). |
| **Naming** | Classes: `Wowexfow_Plugin_*` (WordPress style). Files: `class-{slug}.php`. Functions: `wowexfow_*()` or `wow_*()` for legacy. |
| **No namespaces** | All global; prefix-based collision avoidance. |
| **Singleton pattern** | Core classes (`Wowexfow_Plugin`, `_Admin`, `_Manager`). Extensions are plain `new ClassName()`. |
| **i18n** | All user-facing strings use `__()` / `esc_html_e()` with text domain `wow-extensions-for-woocommerce`. |
| **Security** | `ABSPATH` check at top of every PHP file. Nonce verification on all saves. `current_user_can('manage_woocommerce')` for admin actions. `wp_kses()` for SVG output. |
| **Escaping** | Output escaped with `esc_html()`, `esc_attr()`, `esc_url()`. |
| **Sanitization** | Inputs sanitized with `sanitize_text_field()`, `wp_unslash()`, array validation against known values. |
| **PHPCS** | Uses `phpcs:ignore` annotations for intentional WordPress coding standard deviations (e.g., `DiscouragedFunctions` for `load_plugin_textdomain`). |
| **JS** | jQuery-based IIFE, `'use strict'`. No build framework (vanilla + Select2). |
| **CSS** | Vanilla CSS, no preprocessor. BEM-ish class names: `.wow-extensions-*`, `.wow-extensions-rbp-*`. Brand gradient: `linear-gradient(45deg, #e953c5, #9149fd)`. |

---

## 13. WooCommerce Compatibility Declarations

```php
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );  // HPOS
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', __FILE__, true );  // Cart/Checkout blocks
```

---

## 14. Constants

| Constant | Value | Defined In |
|----------|-------|------------|
| `WOWEXFOW_VERSION` | `'1.0.0'` | Main file |
| `WOWEXFOW_PLUGIN_FILE` | `__FILE__` | Main file |
| `WOWEXFOW_PLUGIN_DIR` | `plugin_dir_path(__FILE__)` | Main file |
| `WOWEXFOW_PLUGIN_URL` | `plugin_dir_url(__FILE__)` | Main file |
| `WOWEXFOW_PLUGIN_BASENAME` | `plugin_basename(__FILE__)` | Main file |
| `WOWEXFOW_DEV_MODE` | `WP_DEBUG` fallback | Main file |
| `WOW_PRICING_DISCOUNT_MAIN_URL_PATH` | Extension or WOW plugin URL | RBP extension |

---

## 15. Known Gaps & Gotchas

1. **Missing WOW admin files:** `wow-price-discount-admin.php` and `wow-class-admin-notice.php` are not in this repo. Product-level role price meta boxes won't render without the standalone WOW plugin installed alongside.
2. **Manager instantiates extension classes twice:** `register_features()` does `new $extension_class()` to call `get_feature_info()`, and then `init_extensions()` does `new $extension_class()` again for enabled features. The first instance is discarded.
3. **`package.json` has bloated `dependencies`:** All transitive deps are listed as direct. Only `devDependencies` are needed. Consider removing the `dependencies` block.
4. **Unused file:** `extensions/role-based-pricing/resources/css/bootstrap.css` is not referenced anywhere.
5. **No Composer autoload:** No `composer.json` exists. All class loading is manual `require_once`.
6. **Built assets are gitignored:** A fresh `git clone` requires `npm run build` before production use.
7. **`watch` script uses `&`:** The parallel operator may not work on Windows cmd/PowerShell. Use `npm-run-all` or separate terminals.

---

## 16. Quick Reference for Common Tasks

### Add a new extension
→ See Section 7 above.

### Add a new admin setting for an extension
→ Hook into `wowexfow_feature_settings_content`. Render fields with names like `wowexfow_{slug}[field_name]`. Handle save in `maybe_save_dashboard()` (or add your own `admin_init` handler).

### Change admin UI branding/colors
→ Edit `src/css/admin.css`. Brand gradient is `linear-gradient(45deg, #e953c5, #9149fd)`. Toggle accent is `#c94fd9`.

### Add a new WC price filter
→ Add hooks in the extension's frontend class constructor. Follow the pattern in `Wowexfow_Plugin_Role_Based_Pricing_Frontend`.

### Test with dev assets (unminified)
→ Set `define('WOWEXFOW_DEV_MODE', true);` in `wp-config.php` or ensure `WP_DEBUG` is true. Assets will be served from `src/` instead of `assets/`.

### Build for production
→ `npm install && npm run build`. Output goes to `assets/css/admin.css` and `assets/js/admin.js`.
