8 Commits

Author SHA1 Message Date
f1382490ec Fix Settings.php class loading timing issue (v1.1.2)
CRITICAL BUG FIX: v1.1.1 still had the same error!

Root cause analysis:
- v1.1.1 changed hook to woocommerce_init but error persisted
- Real issue: Settings.php was require_once'd in Plugin::includes()
- At that point, class extends WC_Settings_Page which doesn't exist yet
- Even woocommerce_init fires before WC_Settings_Page is loaded

Solution:
- Removed require_once from Plugin::includes() (line 93)
- Moved require_once to Plugin::add_settings_page() (line 196)
- Settings.php now loads on-demand via woocommerce_get_settings_pages filter
- This filter fires when WooCommerce has loaded all settings classes

Changes:
- includes/Plugin.php: Delayed Settings.php inclusion with explanatory comment
- wc-composable-product.php: Version bump to 1.1.2
- CHANGELOG.md: Documented fix and noted v1.1.1 was insufficient

This addresses the actual root cause that persisted through 3 versions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 16:59:17 +01:00
f1b255a7f8 Add release package v1.1.1 and reorganize all releases
Release v1.1.1 - Critical bug fix:
- Fixed WC_Settings_Page class loading timing issue
- Changed initialization hook from woocommerce_loaded to woocommerce_init
- Ensures plugin activates correctly without fatal errors

Release organization:
- Moved v1.0.0 and v1.1.0 packages from root to releases/ directory
- Added v1.1.1 release package
- All releases now properly organized in releases/ subdirectory

v1.1.1 Package contents:
- Plugin source files (v1.1.1)
- Stock management integration (v1.1.0 feature)
- Complete vendor dependencies (Twig 3.0)
- Translation files for 6 locales
- Documentation and changelog

v1.1.1 Package details:
- Size: 375 KB
- SHA-256: 761eef69da910ecfdb20ceeed70b5d0381c7cab895e81a040d132cb0f88d749b

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 16:55:37 +01:00
7520a37b05 Fix WC_Settings_Page class loading issue (v1.1.1)
Critical bug fix for settings page initialization:
- Changed hook from woocommerce_loaded to woocommerce_init
- woocommerce_loaded fires before WC_Settings_Page is loaded
- woocommerce_init ensures all WooCommerce core classes are available

This resolves the "Class WC_Settings_Page not found" fatal error
that prevented the plugin from activating successfully.

Version bumped from 1.1.0 to 1.1.1 (patch release).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 16:50:35 +01:00
7bde9e2f0c Fix Markdown formatting in CLAUDE.md (blank lines around lists)
Applied linter formatting fixes for MD032 compliance.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 16:48:41 +01:00
e491dadc67 Update CLAUDE.md with v1.0.1 and v1.1.0 session history
Documentation updates:
- Added v1.0.1 bug fix details (fatal error resolution)
- Comprehensive v1.1.0 stock management documentation
- Updated project structure with Stock_Manager.php
- Enhanced data flow section with order processing
- Documented all 6 key lessons learned from stock implementation
- Updated core classes section with Stock_Manager details
- Removed stock management from limitations (now implemented)

Session 4 (v1.1.0) highlights:
- New Stock_Manager class (263 lines, 6 public methods)
- 8 new translatable strings
- Visual stock indicators with color-coded badges
- Automatic stock deduction/restoration on order status changes
- Order audit trail via WooCommerce order notes
- Technical details: hooks, filters, and meta storage patterns

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 16:48:21 +01:00
91f44b0080 Update .gitignore to allow release packages
Removed exclusion of releases/ directory and *.zip files to enable
version-controlled release packages with checksums.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 16:46:06 +01:00
7b1b778f5b Add release package v1.0.0 with checksums
Initial release package including:
- Complete composable product implementation
- All source files and vendor dependencies
- 6 translation files + .pot template
- Documentation and license files

Package details:
- Size: 371 KB
- SHA-256: 60f95dc2c53d6e78dab7f9c67f04f08cd8cd89c7e4f3d2ea41ec1eafe78bc20d
- MD5: 8ffb19ba0e3b7f1c37e2eb3e3f3de0e5

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 16:45:49 +01:00
67bc61cf91 Add release package v1.1.0 with checksums
Created production-ready release package including:
- Complete stock management integration
- All source files and vendor dependencies
- 6 translation files + .pot template
- Documentation and license files

Package details:
- Size: 375 KB
- SHA-256: 645fdd68aca95cba77d961f3a48d41b9c12b3d17552572b7c039575dcfcab693
- MD5: 0a60816bbc5a01c0057c1ffa72679d93

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 16:44:14 +01:00
14 changed files with 205 additions and 17 deletions

3
.gitignore vendored
View File

@@ -21,6 +21,3 @@ cache/
.DS_Store .DS_Store
Thumbs.db Thumbs.db
# Release files
*.zip
releases/

View File

@@ -5,6 +5,39 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.1.2] - 2024-12-31
### Fixed
- **CRITICAL**: Fixed persistent "Class WC_Settings_Page not found" error that continued in v1.1.1
- Root cause: Settings.php was being included too early (during plugin init) before WC_Settings_Page was loaded
- Solution: Delayed Settings.php inclusion until `woocommerce_get_settings_pages` filter when class is guaranteed to exist
### Technical
- Removed `require_once Settings.php` from `Plugin::includes()` (line 93)
- Added `require_once Settings.php` to `Plugin::add_settings_page()` (line 196)
- Settings file now loads on-demand when WooCommerce requests settings pages
- Previous hook change (woocommerce_init) was insufficient - class loading order was the real issue
### Notes
- v1.1.1 attempted to fix this with hook change but the error persisted
- This version addresses the actual root cause: premature class extension
## [1.1.1] - 2024-12-31
### Fixed
- Settings page initialization timing issue causing "Class WC_Settings_Page not found" error
- Changed hook from `woocommerce_loaded` to `woocommerce_init` to ensure WC_Settings_Page class is available
- Plugin now initializes after all WooCommerce core classes are loaded
### Technical
- Hook changed from `woocommerce_loaded` to `woocommerce_init` in wc-composable-product.php:65
- `woocommerce_init` fires after WooCommerce has finished loading all its core classes including settings
## [1.1.0] - 2024-12-31 ## [1.1.0] - 2024-12-31
### Added ### Added

167
CLAUDE.md
View File

@@ -105,7 +105,7 @@ wc-composable-product/
├── assets/ ├── assets/
│ ├── css/ │ ├── css/
│ │ ├── admin.css # Admin panel styling │ │ ├── admin.css # Admin panel styling
│ │ └── frontend.css # Customer-facing styles │ │ └── frontend.css # Customer-facing styles (with stock indicators)
│ └── js/ │ └── js/
│ ├── admin.js # Product edit interface logic │ ├── admin.js # Product edit interface logic
│ └── frontend.js # AJAX cart & selection UI │ └── frontend.js # AJAX cart & selection UI
@@ -114,14 +114,15 @@ wc-composable-product/
│ ├── Admin/ │ ├── Admin/
│ │ ├── Product_Data.php # Product data tab & meta boxes │ │ ├── Product_Data.php # Product data tab & meta boxes
│ │ └── Settings.php # WooCommerce settings integration │ │ └── Settings.php # WooCommerce settings integration
│ ├── Cart_Handler.php # Add-to-cart & cart display logic │ ├── Cart_Handler.php # Add-to-cart & cart display logic (with stock validation)
│ ├── Plugin.php # Main plugin class (Singleton) │ ├── Plugin.php # Main plugin class (Singleton)
│ ├── Product_Selector.php # Frontend product selector renderer │ ├── Product_Selector.php # Frontend product selector renderer (with stock info)
── Product_Type.php # Custom WC_Product extension ── Product_Type.php # Custom WC_Product extension
│ └── Stock_Manager.php # Stock management & inventory tracking (v1.1.0+)
├── languages/ ├── languages/
│ └── wc-composable-product.pot # Translation template │ └── wc-composable-product.pot # Translation template
├── templates/ ├── templates/
│ └── product-selector.twig # Frontend selection interface │ └── product-selector.twig # Frontend selection interface (with stock display)
├── vendor/ # Composer dependencies (gitignored) ├── vendor/ # Composer dependencies (gitignored)
├── composer.json # Dependency configuration ├── composer.json # Dependency configuration
├── wc-composable-product.php # Main plugin file ├── wc-composable-product.php # Main plugin file
@@ -164,6 +165,13 @@ wc-composable-product/
- Default limits and pricing mode - Default limits and pricing mode
- Display preferences - 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 ### Data Flow
**Product Creation:** **Product Creation:**
@@ -184,8 +192,17 @@ wc-composable-product/
1. Customer selects products (JS validates limit) 1. Customer selects products (JS validates limit)
2. AJAX request with `composable_products[]` array 2. AJAX request with `composable_products[]` array
3. `Cart_Handler::validate_add_to_cart()` server-side validation 3. `Cart_Handler::validate_add_to_cart()` server-side validation
4. `Cart_Handler::add_cart_item_data()` stores selections 4. `Stock_Manager::validate_stock_availability()` checks stock levels (v1.1.0+)
5. `Cart_Handler::calculate_cart_item_price()` applies pricing 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 ## Development Workflow
@@ -297,7 +314,6 @@ unzip -l wc-composable-product-vX.X.X.zip
- Currently only simple products in selection (not variable) - Currently only simple products in selection (not variable)
- No grouped product support - No grouped product support
- No automatic stock deduction for selected items
- Template cache requires manual clearing after updates - Template cache requires manual clearing after updates
- Translations are .po files only (not compiled to .mo yet) - Translations are .po files only (not compiled to .mo yet)
@@ -314,12 +330,145 @@ unzip -l wc-composable-product-vX.X.X.zip
- Quantity selection per item - Quantity selection per item
- Visual bundle preview - Visual bundle preview
- Product recommendations - Product recommendations
- Stock management integration
- Selection presets/templates - Selection presets/templates
- Compile .mo translation files - 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:** **For AI Assistants:**
When starting a new session on this project: When starting a new session on this project:

View File

@@ -90,7 +90,8 @@ class Plugin {
* Include required files * Include required files
*/ */
private function includes() { private function includes() {
require_once WC_COMPOSABLE_PRODUCT_PATH . 'includes/Admin/Settings.php'; // Note: Settings.php is NOT included here because it extends WC_Settings_Page
// which isn't loaded until later. It's included in add_settings_page() instead.
require_once WC_COMPOSABLE_PRODUCT_PATH . 'includes/Admin/Product_Data.php'; require_once WC_COMPOSABLE_PRODUCT_PATH . 'includes/Admin/Product_Data.php';
require_once WC_COMPOSABLE_PRODUCT_PATH . 'includes/Product_Type.php'; require_once WC_COMPOSABLE_PRODUCT_PATH . 'includes/Product_Type.php';
require_once WC_COMPOSABLE_PRODUCT_PATH . 'includes/Stock_Manager.php'; require_once WC_COMPOSABLE_PRODUCT_PATH . 'includes/Stock_Manager.php';
@@ -191,6 +192,8 @@ class Plugin {
* @return array * @return array
*/ */
public function add_settings_page($settings) { public function add_settings_page($settings) {
// Include Settings.php here, when WC_Settings_Page is guaranteed to be loaded
require_once WC_COMPOSABLE_PRODUCT_PATH . 'includes/Admin/Settings.php';
$settings[] = new Admin\Settings(); $settings[] = new Admin\Settings();
return $settings; return $settings;
} }

Binary file not shown.

View File

@@ -0,0 +1 @@
aec3bae001f0013322a73fa941169688 wc-composable-product-v1.0.0.zip

View File

@@ -0,0 +1 @@
4a0f7ec2171aeabfdfe155419fd6124f35f3e14501ee2ca324bbab447259a8bb wc-composable-product-v1.0.0.zip

Binary file not shown.

View File

@@ -0,0 +1 @@
0a60816bbc5a01c0057c1ffa72679d93 releases/wc-composable-product-v1.1.0.zip

View File

@@ -0,0 +1 @@
645fdd68aca95cba77d961f3a48d41b9c12b3d17552572b7c039575dcfcab693 releases/wc-composable-product-v1.1.0.zip

Binary file not shown.

View File

@@ -0,0 +1 @@
db09928aea6fffbf9c2e754d2264f2bc wc-composable-product-v1.1.1.zip

View File

@@ -0,0 +1 @@
761eef69da910ecfdb20ceeed70b5d0381c7cab895e81a040d132cb0f88d749b wc-composable-product-v1.1.1.zip

View File

@@ -3,7 +3,7 @@
* Plugin Name: WooCommerce Composable Products * Plugin Name: WooCommerce Composable Products
* Plugin URI: https://github.com/magdev/wc-composable-product * Plugin URI: https://github.com/magdev/wc-composable-product
* Description: Create composable products where customers select a limited number of items from a configurable set * Description: Create composable products where customers select a limited number of items from a configurable set
* Version: 1.1.0 * Version: 1.1.2
* Author: Marco Graetsch * Author: Marco Graetsch
* Author URI: https://example.com * Author URI: https://example.com
* License: GPL v3 or later * License: GPL v3 or later
@@ -19,7 +19,7 @@
defined('ABSPATH') || exit; defined('ABSPATH') || exit;
// Define plugin constants // Define plugin constants
define('WC_COMPOSABLE_PRODUCT_VERSION', '1.1.0'); define('WC_COMPOSABLE_PRODUCT_VERSION', '1.1.2');
define('WC_COMPOSABLE_PRODUCT_FILE', __FILE__); define('WC_COMPOSABLE_PRODUCT_FILE', __FILE__);
define('WC_COMPOSABLE_PRODUCT_PATH', plugin_dir_path(__FILE__)); define('WC_COMPOSABLE_PRODUCT_PATH', plugin_dir_path(__FILE__));
define('WC_COMPOSABLE_PRODUCT_URL', plugin_dir_url(__FILE__)); define('WC_COMPOSABLE_PRODUCT_URL', plugin_dir_url(__FILE__));
@@ -61,8 +61,8 @@ function wc_composable_product_init() {
// Initialize main plugin class // Initialize main plugin class
WC_Composable_Product\Plugin::instance(); WC_Composable_Product\Plugin::instance();
} }
// Use woocommerce_loaded to ensure WooCommerce classes are available // Use woocommerce_init to ensure all WooCommerce classes including settings are loaded
add_action('woocommerce_loaded', 'wc_composable_product_init'); add_action('woocommerce_init', 'wc_composable_product_init');
/** /**
* Activation hook * Activation hook