2025-12-31 00:38:29 +01:00
# 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`
2025-12-31 00:41:38 +01:00
**Translation Template:**
2025-12-31 00:38:29 +01:00
2025-12-31 00:41:38 +01:00
- Base `.pot` file created: `languages/wc-composable-product.pot`
- Ready for translation to any locale
- All translatable strings properly marked with text domain
**Planned Translations:**
- `en_US` - English (United States) [base language]
2025-12-31 00:38:29 +01:00
- `de_DE` - German (Germany, formal)
- `de_DE_informal` - German (Germany, informal "du")
- `de_CH` - German (Switzerland, formal "Sie")
- `de_CH_informal` - German (Switzerland, informal "du")
- `fr_CH` - French (Switzerland)
- `it_CH` - Italian (Switzerland)
2025-12-31 00:41:38 +01:00
Note: Swiss locales should use CHF currency formatting in examples (e.g., "CHF 50.-")
2025-12-31 00:38:29 +01:00
### Create releases
**Important Notes**
- 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!
**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)
2025-12-31 00:41:38 +01:00
## Project Structure
```
wc-composable-product/
├── assets/
│ ├── css/
│ │ ├── admin.css # Admin panel styling
│ │ └── frontend.css # Customer-facing styles
│ └── 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
│ ├── Plugin.php # Main plugin class (Singleton)
│ ├── Product_Selector.php # Frontend product selector renderer
│ └── Product_Type.php # Custom WC_Product extension
├── languages/
│ └── wc-composable-product.pot # Translation template
├── templates/
│ └── product-selector.twig # Frontend selection interface
├── 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
### 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. `Cart_Handler::add_cart_item_data()` stores selections
5. `Cart_Handler::calculate_cart_item_price()` applies pricing
## 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 (2024-12-31)
**What was built:**
- 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)
**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:** 21 files, 2,628 lines of code
**Git workflow:**
- Initial commit to `main` branch
- Created `dev` branch from `main`
- Both branches in sync at v1.0.0
**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) ✓
**Known limitations:**
- Currently only simple products in selection (not variable)
- No grouped product support
- No automatic stock deduction for selected items
- Template cache requires manual clearing after updates
**Future enhancements to consider:**
- Variable product support
- Quantity selection per item
- Visual bundle preview
- Product recommendations
- Stock management integration
- Selection presets/templates
2025-12-31 00:38:29 +01:00
---
2025-12-31 00:41:38 +01:00
**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
2025-12-31 00:38:29 +01:00
Always refer to this document when starting work on this project. Good luck!