# 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` **Available Translations (as of v1.1.22):** - `en_US` - English (United States) - `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) Note: Swiss locales use CHF currency formatting in examples (e.g., "CHF 50.-") ### 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) --- Always refer to this document when starting work on this project. Good luck!