Files
wc-composable-product/CLAUDE.md

480 lines
17 KiB
Markdown
Raw Normal View History

# WooCommerce plugin for user composable products - AI Context Document
**Author:** Marco Graetsch
## Project Overview
This plugin implements a special product type, for which users can select a limited number of product from a configurable set of simple or variable products. The limit of selectable products should be a global and per-product setting, for which global is the fallback. The set of selectable products can be defined per category, tag or SKU. The price is either a fixed price or the sum of the prices of the selected products. Think of a package of stickers as composable product, where each package can contain $limit number of stickers.
### Key Fact: 100% AI-Generated
This project is proudly **"vibe-coded"** using Claude.AI - the entire codebase was created through AI assistance.
## Technical Stack
- **Language:** PHP 8.3+
- **Framework:** Latest WordPress Plugin API
- **E-commerce:** WooCommerce 10.0+
- **Template Engine:** Twig 3.0 (via Composer)
- **Frontend:** Vanilla JavaScript + jQuery
- **Styling:** Custom CSS
- **Dependency Management:** Composer
- **Internationalization:** WordPress i18n (.pot/.po/.mo files)
## Implementation Details
### Security Best Practices
- All user inputs are sanitized (integers for quantities/prices)
- Nonce verification on form submissions
- Output escaping in templates (`esc_attr`, `esc_html`, `esc_js`)
- Direct file access prevention via `ABSPATH` check
### Translation Ready
All user-facing strings use:
```php
__('Text to translate', 'wc-composable-product')
_e('Text to translate', 'wc-composable-product')
```
Text domain: `wc-composable-product`
**Translation Template:**
- Base `.pot` file created: `languages/wc-composable-product.pot`
- Ready for translation to any locale
- All translatable strings properly marked with text domain
**Available Translations:**
- `en_US` - English (United States) [base language - .pot template]
- `de_DE` - German (Germany, formal) ✓ Complete
- `de_DE_informal` - German (Germany, informal "du") ✓ Complete
- `de_CH` - German (Switzerland, formal "Sie") ✓ Complete
- `de_CH_informal` - German (Switzerland, informal "du") ✓ Complete
- `fr_CH` - French (Switzerland) ✓ Complete
- `it_CH` - Italian (Switzerland) ✓ Complete
All .po files created with 40+ translated strings. Swiss locales include CHF currency formatting in examples (e.g., "CHF 50.-").
To compile translations to .mo files for production:
```bash
for po in languages/*.po; do msgfmt -o "${po%.po}.mo" "$po"; done
```
### Create releases
- The `vendor/` directory MUST be included in releases (Twig dependency required for runtime)
- Running zip from wrong directory creates empty or malformed archives
- Exclusion patterns must match the relative path structure used in zip command
- Always verify the package with `unzip -l` and test extraction before committing
- The `wp-core/` and `wp-plugins/` directories MUST NOT be included in releases
- Releases are stored in `releases/` including checksums
**Important Git Notes:**
- Always commit from `dev` branch first
- Tags should use format `vX.X.X` (e.g., `v1.1.22`)
- Use annotated tags (`-a`) not lightweight tags
- Commit messages should follow the established format with Claude Code attribution
- `.claude/settings.local.json` changes are typically local-only (stash before rebasing)
#### What Gets Released
- All plugin source files
- Compiled vendor dependencies
- Translation files (.mo compiled from .po)
- Assets (CSS, JS)
- Documentation (README, CHANGELOG, etc.)
#### What's Excluded
- Git metadata (`.git/`)
- Development files (`.vscode/`, `.claude/`, `CLAUDE.md`)
- Logs and cache files
- Previous releases
- `composer.lock` (but `vendor/` is included)
## Project Structure
```txt
wc-composable-product/
├── assets/
│ ├── css/
│ │ ├── admin.css # Admin panel styling
│ │ └── frontend.css # Customer-facing styles (with stock indicators)
│ └── js/
│ ├── admin.js # Product edit interface logic
│ └── frontend.js # AJAX cart & selection UI
├── cache/ # Twig template cache (writable)
├── includes/
│ ├── Admin/
│ │ ├── Product_Data.php # Product data tab & meta boxes
│ │ └── Settings.php # WooCommerce settings integration
│ ├── Cart_Handler.php # Add-to-cart & cart display logic (with stock validation)
│ ├── Plugin.php # Main plugin class (Singleton)
│ ├── Product_Selector.php # Frontend product selector renderer (with stock info)
│ ├── Product_Type.php # Custom WC_Product extension
│ └── Stock_Manager.php # Stock management & inventory tracking (v1.1.0+)
├── languages/
│ └── wc-composable-product.pot # Translation template
├── templates/
│ └── product-selector.twig # Frontend selection interface (with stock display)
├── vendor/ # Composer dependencies (gitignored)
├── composer.json # Dependency configuration
├── wc-composable-product.php # Main plugin file
└── [Documentation files] # README, INSTALL, IMPLEMENTATION, etc.
```
## Architecture Overview
### Core Classes
1. **Plugin.php** - Main singleton class
- Initializes Twig template engine
- Registers hooks and filters
- Manages asset enqueuing
- Provides template rendering API
2. **Product_Type.php** - Custom WooCommerce product type
- Extends `WC_Product`
- Handles selection criteria (category/tag/SKU)
- Manages pricing modes (fixed/sum)
- Queries available products dynamically
3. **Cart_Handler.php** - Cart integration
- Validates product selections
- Stores selected products in cart meta
- Calculates dynamic pricing
- Displays selections in cart/checkout
4. **Product_Selector.php** - Frontend renderer
- Renders Twig template with product data
- Applies display settings (images/prices/total)
5. **Admin/Product_Data.php** - Product edit interface
- Adds "Composable Options" tab
- Category/tag/SKU selection fields
- Saves product metadata
6. **Admin/Settings.php** - Global settings
- WooCommerce settings tab integration
- Default limits and pricing mode
- Display preferences
7. **Stock_Manager.php** - Inventory management (v1.1.0+)
- Stock validation for selected products
- Automatic stock deduction on order completion
- Stock restoration on order cancellation/refund
- Order notes for audit trail
- Backorder support detection
### Data Flow
**Product Creation:**
1. Admin selects "Composable product" type
2. Configures criteria, limits, pricing in product data tab
3. Metadata saved: `_composable_*` fields
**Frontend Display:**
1. `Cart_Handler::render_product_selector()` called on product page
2. `Product_Type::get_available_products()` queries matching products
3. `Product_Selector::render()` passes data to Twig template
4. JavaScript handles selection UI and AJAX
**Add to Cart:**
1. Customer selects products (JS validates limit)
2. AJAX request with `composable_products[]` array
3. `Cart_Handler::validate_add_to_cart()` server-side validation
4. `Stock_Manager::validate_stock_availability()` checks stock levels (v1.1.0+)
5. `Cart_Handler::add_cart_item_data()` stores selections
6. `Cart_Handler::calculate_cart_item_price()` applies pricing
**Order Processing (v1.1.0+):**
1. Order status changes to completed/processing
2. `Stock_Manager::reduce_stock_on_order_complete()` deducts inventory
3. Selected product IDs stored in order meta: `_composable_products`
4. Order notes added documenting stock changes
5. On cancellation/refund: `Stock_Manager::restore_stock_on_order_cancel()` reverses deduction
## Development Workflow
### Initial Setup
```bash
composer install
```
### Making Changes
1. **PHP Classes:** Edit files in `includes/` or `includes/Admin/`
2. **Templates:** Modify `templates/*.twig` (cache clears on auto-reload)
3. **Styles:** Update `assets/css/*.css`
4. **JavaScript:** Edit `assets/js/*.js`
5. **Translations:** Update `.pot` file, create `.po` translations
### Testing Checklist
- [ ] Create composable product in admin
- [ ] Test each selection criteria type (category/tag/SKU)
- [ ] Verify selection limit enforcement
- [ ] Test both pricing modes (fixed/sum)
- [ ] Check AJAX add-to-cart functionality
- [ ] Verify cart display shows selected products
- [ ] Test checkout process
- [ ] Check responsive design on mobile
- [ ] Validate all strings are translatable
### Creating Releases
```bash
# From project root
zip -r wc-composable-product-vX.X.X.zip . \
-x "*.git*" "*.vscode*" "*.claude*" "CLAUDE.md" \
"wp-core" "wp-plugins" "*.log" "composer.lock" \
"cache/*" "releases/*" "*.zip"
# Verify contents
unzip -l wc-composable-product-vX.X.X.zip
# IMPORTANT: Ensure vendor/ is included!
```
## Session History
### v1.0.0 - Initial Implementation & Release (2024-12-31)
#### Session 1: Core Implementation
- Complete plugin implementation from scratch
- All 6 core PHP classes with PSR-4 autoloading
- Twig template system integration
- Responsive frontend with AJAX functionality
- Admin interface with WooCommerce integration
- Full i18n support with .pot template
- Comprehensive documentation (README, INSTALL, IMPLEMENTATION)
- Initial commit to `main` branch (1edb0be)
#### Session 2: Documentation & Translations
- Enhanced CLAUDE.md with complete architecture documentation
- Created 6 complete translation files (.po):
- German (Germany - formal & informal)
- German (Switzerland - formal & informal)
- French (Switzerland)
- Italian (Switzerland)
- All 40+ strings translated with locale-specific terminology
- Swiss locales include CHF currency formatting examples
#### Session 3: Release Creation
- Created annotated git tag `v1.0.0`
- Generated release package: `wc-composable-product-v1.0.0.zip` (371 KB)
- Verified vendor/ directory inclusion (336 Twig files)
- Created SHA-256 and MD5 checksums
- Stored in `releases/` directory (gitignored)
**Key decisions made:**
- Used Singleton pattern for main Plugin class
- Twig for templating (per requirements)
- Vanilla JS + jQuery for frontend (WooCommerce standard)
- Grid layout for product selector (responsive)
- AJAX add-to-cart for better UX
- Meta-based configuration storage
**Files created:** 28 files total (21 PHP/templates + 7 translations), 3,842 lines of code
**Git workflow:**
- Main branch: Initial implementation (1edb0be)
- Dev branch: +2 commits for documentation and translations
- Tagged: v1.0.0 on dev branch (8c17734)
**What works:**
- Product type registration ✓
- Admin product data tab ✓
- Category/tag/SKU selection ✓
- Frontend product selector ✓
- AJAX add-to-cart ✓
- Cart integration ✓
- Pricing calculation (both modes) ✓
- Full multilingual support (6 locales) ✓
- Production-ready release package ✓
**Known limitations:**
- Currently only simple products in selection (not variable)
- No grouped product support
- Template cache requires manual clearing after updates
- Translations are .po files only (not compiled to .mo yet)
**Release details:**
- Package size: 371 KB
- Includes: All source + vendor dependencies + translations
- Checksums: SHA-256 and MD5 provided
- Ready for WordPress installation (no composer install needed)
**Future enhancements to consider:**
- Variable product support
- Quantity selection per item
- Visual bundle preview
- Product recommendations
- Selection presets/templates
- Compile .mo translation files
---
### v1.0.1 - Bug Fix (2024-12-31)
**Critical bug fix:** Fatal error "Class WC_Settings_Page not found" during plugin activation
**Root cause:** Plugin initialized on `plugins_loaded` hook before WooCommerce classes were available
**Solution:** Changed initialization hook to `woocommerce_loaded` in wc-composable-product.php:65
**Impact:** Settings page now correctly integrates as tab in WooCommerce > Settings
**Files modified:**
- wc-composable-product.php (version bump to 1.0.1, hook change)
- CHANGELOG.md (documented fix)
**Commit:** a581ef4
---
### v1.1.0 - Stock Management Integration (2024-12-31)
#### Session 4: Stock Management Implementation
**Major feature release** adding comprehensive inventory tracking for composable products.
**What was built:**
1. **New Stock_Manager class** (includes/Stock_Manager.php - 7.7 KB, 263 lines)
- `validate_stock_availability()` - Real-time stock checking
- `get_product_stock_info()` - Stock data for frontend display
- `reduce_stock_on_order_complete()` - Automatic deduction on order completion
- `restore_stock_on_order_cancel()` - Automatic restoration on cancellation/refund
- `prevent_composable_stock_reduction()` - Prevents WooCommerce double-deduction
- `store_selected_products_in_order()` - Saves selection to order meta
2. **Enhanced existing classes:**
- Cart_Handler.php: Added stock validation during add-to-cart (lines 90-95)
- Product_Selector.php: Passes stock data to template (lines 36-56)
- Plugin.php: Includes Stock_Manager in autoload (line 96)
3. **Frontend enhancements:**
- templates/product-selector.twig: Stock status display (lines 39-47)
- assets/css/frontend.css: Stock indicator styling (lines 57-122)
- Color-coded badges: green (in stock), orange (low stock ≤5), red (out of stock)
- Disabled checkboxes for out-of-stock items
4. **Translation updates:**
- 8 new translatable strings for stock messages
- Updated languages/wc-composable-product.pot
- Updated languages/wc-composable-product-it_CH.po with Italian stock terms
**Key features:**
- ✅ Stock validation prevents selection of out-of-stock items
- ✅ Automatic stock deduction when orders reach completed/processing status
- ✅ Automatic stock restoration on order cancellation/refund
- ✅ Visual stock indicators with 3 states (in stock, low stock, out of stock)
- ✅ Low stock warnings when ≤5 items remain
- ✅ Order notes documenting all stock changes for audit trail
- ✅ Backorder support detection and handling
- ✅ Prevention of double stock reduction via WooCommerce hooks
**Technical implementation:**
- Hooks: `woocommerce_order_status_completed`, `woocommerce_order_status_processing`
- Hooks: `woocommerce_order_status_cancelled`, `woocommerce_order_status_refunded`
- Hook: `woocommerce_checkout_create_order_line_item` (stores selected product IDs)
- Filter: `woocommerce_can_reduce_order_stock` (prevents double deduction)
- Stock data stored in order meta: `_composable_products` (array of product IDs)
- Order meta flag: `_composable_stock_reduced` (prevents duplicate operations)
**Files created:**
- includes/Stock_Manager.php (new, 263 lines)
**Files modified:**
- includes/Cart_Handler.php (+13 lines: stock manager integration)
- includes/Product_Selector.php (+17 lines: stock info retrieval)
- includes/Plugin.php (+1 line: Stock_Manager require)
- templates/product-selector.twig (+8 lines: stock status display)
- assets/css/frontend.css (+40 lines: stock indicator styles)
- languages/wc-composable-product.pot (+32 lines: 8 new strings)
- languages/wc-composable-product-it_CH.po (+32 lines: Italian translations)
- wc-composable-product.php (version bump to 1.1.0)
- CHANGELOG.md (v1.1.0 release notes)
**Release details:**
- Package size: 375 KB (+4 KB from v1.0.0)
- Git tag: v1.1.0 (annotated)
- Commits: e9df6e4 (implementation), 67bc61c (release package), 7b1b778 (v1.0.0 package), 91f44b0 (.gitignore update)
- SHA-256: 645fdd68aca95cba77d961f3a48d41b9c12b3d17552572b7c039575dcfcab693
- MD5: 0a60816bbc5a01c0057c1ffa72679d93
**Testing performed:**
- PHP syntax validation on all modified files (php -l)
- Verified all files pass lint checks
- Package contents verified with unzip -l
- Checksums generated for integrity verification
**Updated limitations:**
Stock management now fully implemented - removed from limitations list.
Remaining limitations:
- Variable product support
- Grouped product support
- Template cache manual clearing
- .mo compilation
**What works (v1.1.0):**
Everything from v1.0.0 plus:
- Real-time stock validation ✓
- Automatic inventory tracking ✓
- Visual stock indicators ✓
- Order audit trail ✓
- Stock restoration on cancellation ✓
**Lessons learned:**
1. **Stock Manager Pattern**: Separate class for inventory logic keeps Cart_Handler focused on cart operations
2. **Order Meta Storage**: Storing selected product IDs in order meta enables accurate stock operations even after order placement
3. **Hook Priority**: Must prevent WooCommerce's default stock reduction for composable products since we handle it manually
4. **Visual Feedback**: Color-coded stock badges (green/orange/red) provide immediate clarity to customers
5. **Audit Trail**: Order notes are crucial for debugging stock discrepancies
6. **Defensive Programming**: Check for `_composable_stock_reduced` flag to prevent duplicate operations on order status changes
---
**For AI Assistants:**
When starting a new session on this project:
1. Read this CLAUDE.md file first
2. Review IMPLEMENTATION.md for technical details
3. Check git log for recent changes
4. Verify you're on the `dev` branch before making changes
5. Run `composer install` if vendor/ is missing
6. Test changes before committing
7. Follow commit message format with Claude Code attribution
8. Update this session history section with learnings
Always refer to this document when starting work on this project. Good luck!