You've already forked wc-tier-and-package-prices
Fixed: - Admin table borders still visible despite v1.2.3 fix - added !important flags - Help icon positioning at right edge instead of next to label - changed to flexbox layout - Increased checkbox margin from 8px to 12px for better spacing Technical: - Added border-collapse: collapse !important to force borderless tables - Changed label layout from float to inline-flex for proper help-tip positioning - Added comprehensive border removal with !important on all table elements 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
752 lines
30 KiB
Markdown
752 lines
30 KiB
Markdown
# WooCommerce Tier and Package Prices - AI Context Document
|
|
|
|
**Last Updated:** 2025-12-29
|
|
**Current Version:** 1.2.4
|
|
**Author:** Marco Graetsch
|
|
**Project Status:** Production-ready WordPress plugin
|
|
|
|
## Project Overview
|
|
|
|
This is a WooCommerce plugin that adds flexible pricing capabilities to products through two distinct pricing models:
|
|
|
|
1. **Tier Pricing (Volume Discounts)**: Progressive discounts based on quantity ranges (e.g., 1-9 items @ $12, 10-24 @ $10, 25+ @ $8)
|
|
2. **Package Pricing (Fixed Bundles)**: Exact quantity packages at fixed prices (e.g., exactly 10 items for $95, exactly 25 for $200)
|
|
|
|
### 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 7.4+
|
|
- **Framework:** WordPress Plugin API
|
|
- **E-commerce:** WooCommerce 8.0+ (tested up to 10.x)
|
|
- **Template Engine:** Twig 3.0 (via Composer)
|
|
- **Frontend:** Vanilla JavaScript + jQuery
|
|
- **Styling:** Custom CSS
|
|
- **Dependency Management:** Composer
|
|
- **Internationalization:** WordPress i18n (.pot/.po/.mo files)
|
|
|
|
### Dependencies
|
|
|
|
```json
|
|
{
|
|
"twig/twig": "^3.0",
|
|
"symfony/polyfill-ctype": "^1.x",
|
|
"symfony/polyfill-mbstring": "^1.x"
|
|
}
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Directory Structure
|
|
|
|
```txt
|
|
wc-tier-and-package-prices/
|
|
├── wc-tier-and-package-prices.php # Main plugin file (entry point)
|
|
├── includes/ # PHP classes
|
|
│ ├── class-wc-tpp-admin.php # Admin settings integration
|
|
│ ├── class-wc-tpp-settings.php # WooCommerce settings page
|
|
│ ├── class-wc-tpp-product-meta.php # Product edit page meta boxes
|
|
│ ├── class-wc-tpp-frontend.php # Product page display logic
|
|
│ ├── class-wc-tpp-cart.php # Cart price calculations
|
|
│ └── class-wc-tpp-template-loader.php # Twig template loader
|
|
├── templates/ # Twig templates
|
|
│ ├── admin/ # Admin interface templates
|
|
│ │ ├── tier-row.twig # Single tier input row
|
|
│ │ └── package-row.twig # Single package input row
|
|
│ └── frontend/ # Customer-facing templates
|
|
│ ├── pricing-table.twig # Main pricing display wrapper
|
|
│ ├── tier-pricing-table.twig # Tier pricing display
|
|
│ └── package-pricing-display.twig # Package buttons/cards
|
|
├── assets/
|
|
│ ├── css/
|
|
│ │ ├── admin.css # Backend styling
|
|
│ │ └── frontend.css # Product page & cart styling
|
|
│ └── js/
|
|
│ ├── admin.js # Meta box interaction (add/remove rows)
|
|
│ └── frontend.js # Dynamic price updates, package selection
|
|
├── languages/ # Translation files
|
|
│ ├── *.pot # Translation template
|
|
│ ├── *.po # Translation sources
|
|
│ └── *.mo # Compiled translations
|
|
├── vendor/ # Composer dependencies (included in releases)
|
|
├── releases/ # Release packages (not in git)
|
|
└── *.md # Documentation files
|
|
|
|
```
|
|
|
|
### Class Responsibilities
|
|
|
|
#### 1. `WC_Tier_Package_Prices` (Main Plugin Class)
|
|
|
|
- **Location:** `wc-tier-and-package-prices.php`
|
|
- **Pattern:** Singleton
|
|
- **Responsibilities:**
|
|
- Plugin initialization and bootstrapping
|
|
- Loading all component classes via `includes()`
|
|
- HPOS (High-Performance Order Storage) compatibility declaration
|
|
- Text domain loading for internationalization
|
|
- Activation/deactivation hooks
|
|
|
|
#### 2. `WC_TPP_Admin`
|
|
|
|
- **Location:** `includes/class-wc-tpp-admin.php`
|
|
- **Pattern:** Singleton
|
|
- **Responsibilities:**
|
|
- Enqueues admin CSS/JS
|
|
- Registers WooCommerce settings page via filter
|
|
- Manages settings page instance (cached to prevent duplicates)
|
|
- Product meta box asset loading
|
|
|
|
#### 3. `WC_TPP_Settings`
|
|
|
|
- **Location:** `includes/class-wc-tpp-settings.php`
|
|
- **Extends:** `WC_Settings_Page` (WooCommerce core)
|
|
- **Responsibilities:**
|
|
- Creates "Tier & Package Prices" tab in WooCommerce settings
|
|
- Defines global plugin settings (enable/disable features, display position, etc.)
|
|
- Setting persistence through WooCommerce options API
|
|
|
|
**Global Settings:**
|
|
|
|
- `wc_tpp_enable_tier_pricing` (yes/no)
|
|
- `wc_tpp_enable_package_pricing` (yes/no)
|
|
- `wc_tpp_display_table` (yes/no) - Show pricing tables on product pages
|
|
- `wc_tpp_display_position` (before_add_to_cart / after_add_to_cart / after_price)
|
|
- `wc_tpp_restrict_package_quantities` (yes/no) - Global quantity restrictions
|
|
|
|
#### 4. `WC_TPP_Product_Meta`
|
|
|
|
- **Location:** `includes/class-wc-tpp-product-meta.php`
|
|
- **Responsibilities:**
|
|
- Adds tier/package pricing fields to product edit page
|
|
- Renders Twig templates for meta box rows
|
|
- Saves tier/package data to post meta
|
|
- Nonce verification and capability checks for security
|
|
- Prevents autosave from corrupting data
|
|
|
|
**Product Meta Keys:**
|
|
|
|
- `_wc_tpp_tiers` - Array of tier objects `[{min_qty, price, label}]`
|
|
- `_wc_tpp_packages` - Array of package objects `[{qty, price, label}]`
|
|
- `_wc_tpp_restrict_to_packages` - Per-product quantity restriction (yes/no)
|
|
|
|
#### 5. `WC_TPP_Frontend`
|
|
|
|
- **Location:** `includes/class-wc-tpp-frontend.php`
|
|
- **Responsibilities:**
|
|
- Enqueues frontend CSS/JS on product pages
|
|
- Displays pricing tables via Twig templates
|
|
- Localizes currency settings to JavaScript
|
|
- Hides quantity inputs for restricted products
|
|
- Modifies catalog "Add to Cart" buttons to "View Options" for restricted products
|
|
- Static methods for price lookups (`get_tier_price()`, `get_package_price()`)
|
|
|
|
#### 6. `WC_TPP_Cart`
|
|
|
|
- **Location:** `includes/class-wc-tpp-cart.php`
|
|
- **Responsibilities:**
|
|
- **MOST CRITICAL CLASS** - Handles all cart price calculations
|
|
- Applies tier/package pricing during cart totals calculation
|
|
- Stores pricing metadata in cart items for display
|
|
- Customizes cart item display (price labels, quantity indicators)
|
|
- Validates package quantities on add-to-cart
|
|
- Hides/disables quantity inputs for restricted products (classic cart + blocks)
|
|
- **WooCommerce Blocks support** via `woocommerce_store_api_product_quantity_editable` filter
|
|
|
|
**Price Calculation Priority (in `apply_tier_package_pricing()`):**
|
|
|
|
1. Check for exact package match → Use package price if found
|
|
2. Check for tier match → Use tier price if found
|
|
3. Fall back to regular product price
|
|
|
|
#### 7. `WC_TPP_Template_Loader`
|
|
|
|
- **Location:** `includes/class-wc-tpp-template-loader.php`
|
|
- **Pattern:** Singleton
|
|
- **Responsibilities:**
|
|
- Initializes Twig environment with proper paths
|
|
- Renders Twig templates from both admin and frontend directories
|
|
- Handles template caching and error handling
|
|
|
|
## Important Implementation Details
|
|
|
|
### Price Calculation Logic
|
|
|
|
**Package Pricing** (exact match):
|
|
|
|
```php
|
|
// In cart: if quantity == 10 and package exists for 10, use package price
|
|
if ($quantity == $package['qty']) {
|
|
$unit_price = $package['price'] / $quantity; // Total price divided by quantity
|
|
$product->set_price($unit_price); // WooCommerce expects unit price
|
|
}
|
|
```
|
|
|
|
**Tier Pricing** (range-based):
|
|
|
|
```php
|
|
// In cart: if quantity >= 10, use tier price for quantities 10+
|
|
foreach ($tiers as $tier) {
|
|
if ($quantity >= $tier['min_qty']) {
|
|
$applicable_price = $tier['price']; // This is already unit price
|
|
}
|
|
}
|
|
$product->set_price($applicable_price);
|
|
```
|
|
|
|
### Quantity Restriction Feature
|
|
|
|
Products can be configured to ONLY allow purchase in package quantities:
|
|
|
|
- **Global setting:** `wc_tpp_restrict_package_quantities`
|
|
- **Per-product setting:** `_wc_tpp_restrict_to_packages`
|
|
- **When enabled:**
|
|
- Quantity inputs are hidden on product page, cart, and mini-cart
|
|
- Customers must use package selection buttons
|
|
- Validation prevents arbitrary quantities from being added
|
|
- Catalog buttons change to "View Options" instead of "Add to Cart"
|
|
|
|
### WooCommerce Blocks Compatibility
|
|
|
|
**CRITICAL BUG FIXED in v1.1.20:**
|
|
|
|
- Filter `woocommerce_store_api_product_quantity_editable` passes `WC_Product` object, NOT cart item array
|
|
- Previous code tried to use product object as array → fatal error
|
|
- Fixed by accepting product object and using `$product->get_id()`
|
|
|
|
### Cart Item Metadata
|
|
|
|
The plugin stores additional data in cart items for display purposes:
|
|
|
|
```php
|
|
WC()->cart->cart_contents[$cart_item_key]['wc_tpp_pricing_type'] = 'package' | 'tier';
|
|
WC()->cart->cart_contents[$cart_item_key]['wc_tpp_total_price'] = 99.99; // For packages
|
|
WC()->cart->cart_contents[$cart_item_key]['wc_tpp_unit_price'] = 9.99; // For tiers
|
|
```
|
|
|
|
This metadata is used by display filters to show "(Package price)" or "(Volume discount)" labels.
|
|
|
|
## Common Patterns & Conventions
|
|
|
|
### Class Instantiation Pattern
|
|
|
|
All classes auto-instantiate at the end of their file:
|
|
|
|
```php
|
|
if (!class_exists('WC_TPP_Frontend')) {
|
|
class WC_TPP_Frontend {
|
|
// class code
|
|
}
|
|
}
|
|
new WC_TPP_Frontend(); // Auto-instantiate
|
|
```
|
|
|
|
**Exception:** Admin and Settings classes use singleton pattern to prevent duplicates.
|
|
|
|
### Security Best Practices
|
|
|
|
- All user inputs are sanitized (integers for quantities/prices)
|
|
- Nonce verification on form submissions
|
|
- Capability checks (`edit_products`) before saving
|
|
- 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-tier-package-prices')
|
|
_e('Text to translate', 'wc-tier-package-prices')
|
|
```
|
|
|
|
Text domain: `wc-tier-package-prices`
|
|
|
|
**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.-")
|
|
|
|
## Known Issues & Historical Context
|
|
|
|
### Settings Page Duplication Saga (v1.1.15-1.1.19)
|
|
|
|
Multiple versions attempted to fix settings page appearing twice:
|
|
|
|
- **Root cause:** Settings file auto-instantiation + Composer autoloader
|
|
- **Solution:** Removed auto-instantiation from settings file, explicit instantiation in admin class
|
|
- **Prevention:** Singleton pattern + duplicate detection in array
|
|
|
|
### Class Redeclaration Issues (v1.1.8-1.1.14)
|
|
|
|
Plugin was completely non-functional:
|
|
|
|
- **Cause:** Incorrect initialization pattern without `class_exists()` guards
|
|
- **Solution:** Added guards and restored direct instantiation pattern
|
|
- **Lesson:** Always wrap class declarations in `class_exists()` checks
|
|
|
|
### WooCommerce Blocks Fatal Error (v1.1.19 → v1.1.20)
|
|
|
|
```txt
|
|
Fatal error: Cannot use object of type WC_Product_Simple as array
|
|
Location: includes/class-wc-tpp-cart.php:233
|
|
```
|
|
|
|
- **Cause:** Filter signature mismatch - expected array, received product object
|
|
- **Fix:** Changed method signature to accept `WC_Product $product` instead of `$cart_item` array
|
|
- **Status:** FIXED in v1.1.20
|
|
|
|
## Release Process
|
|
|
|
### Version Bumping
|
|
|
|
Update version in 3 places:
|
|
|
|
1. `wc-tier-and-package-prices.php` - Plugin header comment (line 7)
|
|
2. `wc-tier-and-package-prices.php` - `WC_TPP_VERSION` constant (line 26)
|
|
3. `composer.json` - version field (optional, not critical)
|
|
|
|
### Creating Release Package
|
|
|
|
**CRITICAL:** The zip command must be run from the **parent directory** of the plugin folder to create proper archive structure.
|
|
|
|
```bash
|
|
# From parent directory (/home/magdev/workspaces/node)
|
|
cd /home/magdev/workspaces/node
|
|
|
|
# Create zip excluding dev files - note the correct path structure
|
|
zip -r wc-tier-and-package-prices/releases/wc-tier-and-package-prices-X.X.X.zip wc-tier-and-package-prices/ \
|
|
-x 'wc-tier-and-package-prices/.git*' \
|
|
'wc-tier-and-package-prices/*.log' \
|
|
'wc-tier-and-package-prices/.claude/*' \
|
|
'wc-tier-and-package-prices/CLAUDE.md' \
|
|
'wc-tier-and-package-prices/releases/*' \
|
|
'wc-tier-and-package-prices/node_modules/*' \
|
|
'wc-tier-and-package-prices/.DS_Store' \
|
|
'wc-tier-and-package-prices/Thumbs.db' \
|
|
'wc-tier-and-package-prices/.vscode/*' \
|
|
'wc-tier-and-package-prices/.idea/*' \
|
|
'wc-tier-and-package-prices/*.sublime-*' \
|
|
'wc-tier-and-package-prices/notes.*' \
|
|
'wc-tier-and-package-prices/logs/*' \
|
|
'wc-tier-and-package-prices/templates/cache/*' \
|
|
'wc-tier-and-package-prices/composer.lock'
|
|
|
|
# Return to project directory
|
|
cd wc-tier-and-package-prices
|
|
|
|
# Generate checksums
|
|
cd releases
|
|
md5sum wc-tier-and-package-prices-X.X.X.zip > wc-tier-and-package-prices-X.X.X.zip.md5
|
|
sha256sum wc-tier-and-package-prices-X.X.X.zip > wc-tier-and-package-prices-X.X.X.zip.sha256
|
|
cd ..
|
|
```
|
|
|
|
**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
|
|
|
|
### Verification Steps
|
|
|
|
After creating the release package, always verify:
|
|
|
|
```bash
|
|
# Check package size (should be ~400-450KB, NOT 8MB+ or near 0)
|
|
ls -lh releases/wc-tier-and-package-prices-X.X.X.zip
|
|
|
|
# Verify exclusions worked
|
|
unzip -l releases/wc-tier-and-package-prices-X.X.X.zip | grep -E "CLAUDE\.md|\.claude/|\.git" && echo "ERROR: Excluded files found!" || echo "OK: No excluded files"
|
|
|
|
# Test extraction
|
|
cd /tmp && rm -rf test-extract && unzip -q /path/to/releases/wc-tier-and-package-prices-X.X.X.zip -d test-extract && ls -la test-extract/wc-tier-and-package-prices/
|
|
|
|
# Verify version in extracted package
|
|
head -30 /tmp/test-extract/wc-tier-and-package-prices/wc-tier-and-package-prices.php | grep -E "Version:|WC_TPP_VERSION"
|
|
|
|
# Verify template changes (if applicable)
|
|
grep 'class="regular"' /tmp/test-extract/wc-tier-and-package-prices/templates/admin/*.twig
|
|
```
|
|
|
|
### Git Workflow for Releases
|
|
|
|
**Standard workflow:** Work on `dev` branch → merge to `main` → tag → push
|
|
|
|
```bash
|
|
# 1. Ensure you're on dev branch with all changes committed
|
|
git checkout dev
|
|
git add [files]
|
|
git commit -m "Release version X.X.X - [description]
|
|
|
|
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
|
|
|
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
|
|
|
|
# 2. Merge dev to main
|
|
git checkout main
|
|
git merge dev --no-edit # Should be fast-forward
|
|
|
|
# 3. Create annotated tag
|
|
git tag -a vX.X.X -m "Release version X.X.X - [description]"
|
|
|
|
# 4. Push everything
|
|
git push origin main
|
|
git push origin vX.X.X
|
|
|
|
# 5. Update dev and push
|
|
git checkout dev
|
|
git rebase main # Should be up-to-date already
|
|
git push origin dev
|
|
|
|
# 6. If you have uncommitted local changes (like .claude/settings.local.json)
|
|
git stash push -m "Local development settings"
|
|
# ... do git operations ...
|
|
git stash pop
|
|
```
|
|
|
|
**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)
|
|
|
|
## Testing Checklist
|
|
|
|
When making changes, test these critical paths:
|
|
|
|
### Admin
|
|
|
|
- [ ] Settings page appears once under WooCommerce > Tier & Package Prices
|
|
- [ ] Settings save correctly
|
|
- [ ] Product edit page shows tier/package meta boxes
|
|
- [ ] Adding/removing tiers works
|
|
- [ ] Adding/removing packages works
|
|
- [ ] Data saves when clicking "Update" on product
|
|
|
|
### Frontend (Product Page)
|
|
|
|
- [ ] Pricing tables display when configured
|
|
- [ ] Package buttons update quantity selector
|
|
- [ ] Price updates dynamically when quantity changes
|
|
- [ ] Restricted products hide quantity input
|
|
- [ ] "View Options" appears on catalog for restricted products
|
|
|
|
### Cart & Checkout
|
|
|
|
- [ ] Correct prices applied for tier pricing
|
|
- [ ] Correct prices applied for package pricing
|
|
- [ ] Cart displays pricing type labels
|
|
- [ ] Package quantities can't be edited if restricted
|
|
- [ ] Prices recalculate if quantity changed (non-restricted products)
|
|
- [ ] Checkout totals are correct
|
|
|
|
### WooCommerce Blocks (Critical!)
|
|
|
|
- [ ] Mini cart block doesn't throw fatal errors
|
|
- [ ] Cart block works correctly
|
|
- [ ] Checkout block processes orders
|
|
- [ ] Quantity editable flag works for blocks
|
|
|
|
## Development Tips for Future AI Assistants
|
|
|
|
### Common Pitfalls and Solutions
|
|
|
|
#### Release Package Creation
|
|
|
|
**Problem:** Empty or corrupted zip files (0 bytes or wrong structure)
|
|
**Cause:** Running zip command from wrong directory or incorrect path patterns
|
|
**Solution:** Always run from parent directory (`/home/magdev/workspaces/node`) and use full relative paths in exclusions
|
|
|
|
**Problem:** Development files included in release (CLAUDE.md, .claude/, .git)
|
|
**Cause:** Exclusion patterns don't match actual paths used in zip command
|
|
**Solution:** Test with `unzip -l | grep` to verify exclusions before committing
|
|
|
|
**Problem:** Package size is 8MB+ instead of ~400KB
|
|
**Cause:** Development files not excluded (especially .git directory)
|
|
**Solution:** Follow verification steps and check package size immediately after creation
|
|
|
|
#### UI Changes in Admin
|
|
|
|
**WooCommerce CSS Classes:**
|
|
|
|
- `short` - Small input fields (~60px width)
|
|
- `regular` - Medium input fields (~120px width)
|
|
- `long` - Large input fields (~200px+ width)
|
|
|
|
When modifying admin input fields in Twig templates, use WooCommerce's standard classes for consistency.
|
|
|
|
**Location:** `templates/admin/*.twig` for admin UI changes
|
|
|
|
#### Git Workflow Issues
|
|
|
|
**Problem:** Cannot rebase due to uncommitted changes
|
|
**Solution:** Stash local config files (`.claude/settings.local.json`) before git operations
|
|
|
|
**Problem:** Tag already exists
|
|
**Solution:** Delete with `git tag -d vX.X.X` locally and `git push --delete origin vX.X.X` remotely
|
|
|
|
**Problem:** Wrong branch for commits
|
|
**Solution:** Always start on `dev` branch, merge to `main`, never commit directly to `main`
|
|
|
|
### Working with Twig Templates
|
|
|
|
The plugin uses Twig 3.0 for templating. Key files:
|
|
|
|
- `templates/admin/tier-row.twig` - Single tier input row in product edit page
|
|
- `templates/admin/package-row.twig` - Single package input row in product edit page
|
|
- `templates/frontend/*.twig` - Customer-facing pricing displays
|
|
|
|
**Template rendering:** Done via `WC_TPP_Template_Loader` singleton class
|
|
|
|
**When modifying templates:**
|
|
|
|
1. Templates are cached - clear cache or test in development mode
|
|
2. Always escape output: use Twig's built-in filters or `|esc_attr`, `|esc_html`
|
|
3. Translation strings: `{{ 'Text'|__('wc-tier-package-prices') }}`
|
|
4. Keep consistent with WooCommerce admin UI patterns
|
|
|
|
### Complete Release Workflow Summary
|
|
|
|
Based on v1.1.22, v1.2.2, and v1.2.3 release experience, here's the complete workflow:
|
|
|
|
1. **Fix bugs/add features** on `dev` branch
|
|
2. **Update version numbers** (3 files: main plugin file header, constant, composer.json)
|
|
3. **Update CHANGELOG.md** with detailed changes
|
|
4. **Update CLAUDE.md** version number and roadmap
|
|
5. **Create release package** from parent directory with correct exclusions
|
|
6. **Verify package** (size, contents, exclusions, extraction test)
|
|
7. **Commit changes** to `dev` branch with proper message format
|
|
8. **Merge to main** (fast-forward merge)
|
|
9. **Create annotated tag** (`vX.X.X`)
|
|
10. **Push all** (main, tag, dev)
|
|
11. **Verify remote** (check repository web UI)
|
|
|
|
**Time estimate:** 15-20 minutes for full release cycle
|
|
|
|
**Files typically changed in a release:**
|
|
|
|
- `wc-tier-and-package-prices.php` - Version bumps
|
|
- `composer.json` - Version bump
|
|
- `CHANGELOG.md` - Release notes
|
|
- `CLAUDE.md` - Version and roadmap updates
|
|
- `releases/wc-tier-and-package-prices-X.X.X.zip*` - Package and checksums
|
|
- Feature-specific files (templates, PHP classes, etc.)
|
|
|
|
### Release Package Creation - Critical Notes
|
|
|
|
**IMPORTANT:** The zip command must be run from the **parent directory** to create proper archive structure.
|
|
|
|
**Correct command (from `/home/magdev/workspaces/php`):**
|
|
|
|
```bash
|
|
cd /home/magdev/workspaces/php
|
|
zip -r wc-tier-and-package-prices/releases/wc-tier-and-package-prices-X.X.X.zip wc-tier-and-package-prices/ \
|
|
-x '*/\.git/*' '*/.git/*' 'wc-tier-and-package-prices/.git/*' \
|
|
'*.gitignore' '*.log' '*/.claude/*' '*/CLAUDE.md' \
|
|
'*/releases/*' '*/wordpress/*' '*/node_modules/*' \
|
|
'*/.DS_Store' '*/Thumbs.db' '*/.vscode/*' '*/.idea/*' \
|
|
'*.sublime-*' '*/notes.*' '*/logs/*' '*/templates/cache/*' \
|
|
'*/composer.lock'
|
|
```
|
|
|
|
**Critical Exclusions:**
|
|
|
|
- `*/wordpress/*` - MUST be excluded! The project has a symlink to WordPress installation that zip will follow, creating 129MB+ packages instead of ~430KB
|
|
- `.git/*` - All git metadata (multiple patterns needed for reliability)
|
|
- `.claude/*` and `CLAUDE.md` - Development documentation
|
|
- `releases/*` - Prevents including previous releases in new ones
|
|
- `composer.lock` - Not needed in production (vendor/ is included)
|
|
|
|
**Expected Package Size:** ~430-431KB (383 files)
|
|
|
|
**Package Size Alert:** If >1MB, exclusions failed (likely wordpress symlink included)
|
|
|
|
**Verification Steps:**
|
|
|
|
```bash
|
|
# 1. Check size (should be ~430KB)
|
|
ls -lh releases/wc-tier-and-package-prices-X.X.X.zip
|
|
|
|
# 2. Verify file count (should be 383 files)
|
|
unzip -l releases/wc-tier-and-package-prices-X.X.X.zip | tail -1
|
|
|
|
# 3. Check for excluded files
|
|
unzip -l releases/wc-tier-and-package-prices-X.X.X.zip | grep -E "CLAUDE\.md|\.claude/|\.git/|wordpress/"
|
|
# Should return nothing (exit code 1)
|
|
|
|
# 4. Verify version in package
|
|
unzip -p releases/wc-tier-and-package-prices-X.X.X.zip wc-tier-and-package-prices/wc-tier-and-package-prices.php | head -30 | grep -E "Version:|WC_TPP_VERSION"
|
|
```
|
|
|
|
### Future Features and Roadmap
|
|
|
|
The is a hierarchical list for upcoming features and can be considered as a
|
|
Roadmap for the upcoming development.
|
|
|
|
#### Version 1.1.x (Completed)
|
|
|
|
1. ~~Add translations for `de_CH`, `de_DE_informal`, `fr_CH`, `it_CH`~~ ✅ **COMPLETED in v1.1.21**
|
|
2. ~~The double-install bug is back again. A new version of the plugin is installed as new plugin instead of updating the previous version.~~ ✅ **DOCUMENTED in v1.1.22** - Added workaround to CHANGELOG. Root cause: No automatic update mechanism (requires WordPress.org repository or custom update server).
|
|
3. ~~Make the label fields in the backend for tierprices and package-prices twice as long as it is.~~ ✅ **COMPLETED in v1.1.22**
|
|
4. ~~Make the plugin work with variable products~~ ✅ **COMPLETED in v1.2.0** - Full variation-level pricing support with independent configuration per variation, AJAX-based frontend display, and complete WooCommerce Blocks compatibility.
|
|
|
|
#### Version 1.2.x
|
|
|
|
##### Bugfixes (Completed in v1.2.1)
|
|
|
|
1. ~~The admin templates are not show right. The row templates didn't match the new table structure. The table-body columns didn't fit the table-head columns.~~ ✅ **FIXED in v1.2.1** - Updated admin.css to remove flexbox styling that was breaking the new `<table>/<tr>/<td>` structure introduced in v1.2.0. The CSS was still using flexbox layout from the old `<div>/<p>` structure.
|
|
|
|
2. ~~The tier and package prices are not shown on simple product pages~~ ✅ **FIXED in v1.2.1** - Removed global enable/disable checks from frontend template. Pricing tables now display if configured on a product AND the "Display Pricing Table" setting is enabled, regardless of "Enable Tier Pricing" or "Enable Package Pricing" global settings. Cart calculations still respect global enable settings.
|
|
|
|
##### Bugfixes (Completed in v1.2.2)
|
|
|
|
1. ~~Remove the table borders in admin on variable product to better fit the surrounding element styles.~~ ✅ **FIXED in v1.2.2** - Added CSS rules to remove table borders specifically for variation pricing tables (`.wc-tpp-variation-pricing`), matching WooCommerce's borderless variation UI style.
|
|
|
|
2. ~~Add missing translations in admin templates ("Price", "Tier & Package Pricing", "Min Quantity") for all languages used in this project.~~ ✅ **FIXED in v1.2.2** - Added missing translation entries for "Min Quantity", "Price", and "Label (optional)" to all .po files (de_DE, de_DE_informal, de_CH, de_CH_informal, fr_CH, it_CH, en_US) and recompiled .mo files.
|
|
|
|
3. ~~Check the template for wc_tpp_restrict_to_packages[] checkbox elements in admin on variable products and fix the rendering.~~ ✅ **FIXED in v1.2.2** - Fixed checkbox value parameter in variation pricing fields. Changed from ternary expression to direct value assignment, allowing WooCommerce's `woocommerce_wp_checkbox()` to properly handle the checked state.
|
|
|
|
##### Bugfixes (Completed in v1.2.3)
|
|
|
|
1. ~~Style the tier and packages tables in admin on simple products according to the styles on variable products.~~ ✅ **FIXED in v1.2.3** - Applied borderless table styling to all tier/package tables (both simple and variable products). Removed borders from table, th, and td elements to match WooCommerce's clean admin UI style.
|
|
|
|
2. ~~The checkbox styles from 1.2.2 bug 3 are still not looking correct. The helptext is written instead of hidden after the help icon and the margin between checkbox and label are to small.~~ ✅ **FIXED in v1.2.3** - Added `desc_tip => true` to variation checkbox to show tooltip instead of inline text. Added CSS rules to increase checkbox-label margin (8px) and hide inline description text when tooltip is used.
|
|
|
|
##### Bugfixes (Completed in v1.2.4)
|
|
|
|
1. ~~Bug 1 in v1.2.3 is not fixed. Now both table display have border again. they shouldn't have border.~~ ✅ **FIXED in v1.2.4** - Added `!important` flags and `border-collapse: collapse` to table CSS to override WooCommerce's default table styling. Added comprehensive border removal for all table elements (table, thead, tbody, tr, th, td) to ensure truly borderless tables across all browsers.
|
|
|
|
2. ~~Bug 2 in v1.2.3: Increase the margin between checkbox and label and put the help icon right next to the label, not at the right border~~ ✅ **FIXED in v1.2.4** - Increased checkbox right margin from 8px to 12px. Repositioned help tip icon to display inline right next to the label text using flexbox layout with `display: inline-flex`, removing float positioning that caused it to appear at the right edge.
|
|
|
|
##### New Features
|
|
|
|
1. Create different, selectable templates for tierprices and packages to use in the frontend. Make the new templates selectable globally on the settings-page, not per product.
|
|
|
|
### When Debugging Cart Issues
|
|
|
|
1. Check `includes/class-wc-tpp-cart.php` first
|
|
2. The `apply_tier_package_pricing()` method runs on `woocommerce_before_calculate_totals`
|
|
3. Always validate product objects with `is_a($product, 'WC_Product')`
|
|
4. Remember: WooCommerce expects UNIT prices, not total prices (except for internal calculations)
|
|
|
|
### When Working with WooCommerce Hooks
|
|
|
|
- WooCommerce has both classic and block-based systems
|
|
- Classic cart uses different hooks than Store API (blocks)
|
|
- Always check filter/action documentation for parameter types
|
|
- Don't assume cart item arrays everywhere - sometimes it's product objects!
|
|
|
|
### When Adding Features
|
|
|
|
- Follow the existing pattern: add setting → add UI → add logic → add template
|
|
- Use Twig for all new templates (consistency)
|
|
- Add translations for all user-facing strings
|
|
- Test with both simple products and variable products (if applicable)
|
|
- Consider both classic and block-based cart/checkout
|
|
|
|
### When Fixing Bugs
|
|
|
|
1. Check `CHANGELOG.md` for historical context
|
|
2. Look for similar issues in past versions
|
|
3. Always add detailed changelog entry explaining root cause
|
|
4. Consider edge cases (guest checkout, logged-in users, AJAX add-to-cart, etc.)
|
|
|
|
## File Locations Quick Reference
|
|
|
|
| Task | File(s) |
|
|
| ------ | --------- |
|
|
| Change version | `wc-tier-and-package-prices.php` (2 places) |
|
|
| Add global setting | `includes/class-wc-tpp-settings.php` |
|
|
| Modify product meta box | `includes/class-wc-tpp-product-meta.php` + `templates/admin/*.twig` |
|
|
| Change product page display | `includes/class-wc-tpp-frontend.php` + `templates/frontend/*.twig` |
|
|
| Fix cart pricing | `includes/class-wc-tpp-cart.php` |
|
|
| Update styles | `assets/css/frontend.css` or `assets/css/admin.css` |
|
|
| Fix JavaScript bugs | `assets/js/frontend.js` or `assets/js/admin.js` |
|
|
| Add translations | `languages/*.po` then compile to `.mo` |
|
|
| Document changes | `CHANGELOG.md` |
|
|
|
|
## Compatibility Notes
|
|
|
|
### WordPress
|
|
|
|
- Minimum: 6.0
|
|
- Tested up to: 6.9.x
|
|
- Uses standard plugin API, no deprecated functions
|
|
|
|
### WooCommerce
|
|
|
|
- Minimum: 8.0
|
|
- Tested up to: 10.x
|
|
- HPOS compatible (declared via `FeaturesUtil::declare_compatibility`)
|
|
- Blocks compatible (with proper filter handling)
|
|
|
|
### PHP
|
|
|
|
- Minimum: 7.4
|
|
- Uses modern PHP features (type hints acceptable in new code)
|
|
- Composer autoloader handles namespacing
|
|
|
|
### Browsers
|
|
|
|
- Modern browsers (ES6+ JavaScript)
|
|
- Responsive CSS (mobile-friendly)
|
|
- jQuery dependency (WooCommerce provides)
|
|
|
|
## Support & Resources
|
|
|
|
- **Repository:** <https://src.bundespruefstelle.ch/magdev/wc-tier-package-prices>
|
|
- **Documentation:** See `README.md`, `QUICKSTART.md`, `USAGE_EXAMPLES.md`, `INSTALLATION.md`
|
|
- **Changelog:** `CHANGELOG.md` (detailed version history)
|
|
- **Issue Tracking:** Check fatal-errors-*.log files for production errors
|
|
|
|
## Final Notes
|
|
|
|
This is a production-quality plugin with real-world usage. Any changes should:
|
|
|
|
1. Maintain backward compatibility with existing tier/package configurations
|
|
2. Not break WooCommerce core functionality
|
|
3. Work with both classic and block-based themes
|
|
4. Be thoroughly tested before release
|
|
5. Include proper error handling and validation
|
|
6. Update CHANGELOG.md with detailed explanations
|
|
|
|
The plugin architecture is solid and well-tested. Most bugs arise from:
|
|
|
|
- WooCommerce API changes (especially blocks)
|
|
- Filter/action signature changes
|
|
- Edge cases in cart calculations
|
|
- Settings persistence issues
|
|
|
|
---
|
|
|
|
Always refer to this document when starting work on this project. Good luck!
|