52 Commits

Author SHA1 Message Date
669888817b Bump version to 1.1.13 - fix product retrieval issue
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 23:08:53 +01:00
5564b888fc Fix product retrieval - remove strict stock check and add meta_query relation
- Removed is_in_stock() requirement to show all purchasable products
- Stock status still displayed on frontend, out-of-stock items disabled
- Added 'relation' => 'AND' to meta_query for proper multiple condition handling
- Should fix "No products available" issue

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 23:07:06 +01:00
91aca25169 Add release package v1.1.12 with checksums
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 23:03:57 +01:00
4195fb2651 Bump version to 1.1.12 for variable product fix release
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:59:46 +01:00
ba28ae174f Fix variable product variations retrieval
Changed from get_available_variations() to get_children() for more reliable
variation ID retrieval. The previous method returned variation data arrays
which may not have worked correctly in all contexts.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:56:07 +01:00
755108a7d3 Add release package v1.1.11 with checksums
Feature release adding variable product support.

Package: wc-composable-product-v1.1.11.zip (414 KB, 379 files)
SHA-256: 214002a28a0426b4d2423f234d1dff63e4a8e58c6301cbd6eaed8db670db88c6
MD5: 63b105311dc1cc8ac67c05528ad02e30

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:53:00 +01:00
85983d5473 Bump version to 1.1.11 - Add variable product support
Feature release adding support for variable products and their variations.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:51:49 +01:00
252b187600 Add variable product support to product selector
BREAKING CHANGE: Variable products now supported in composable products.

Changes:
- Modified get_available_products() to detect variable products
- Variable products now expand to show all available variations
- Each variation is checked individually for stock and purchasability
- Simple products continue to work as before

This allows customers to select specific variations (e.g., "T-Shirt - Red - Large")
instead of just seeing "T-Shirt" which wasn't selectable.

Fixes the issue where products weren't showing because all products
in the category/tag were variable products.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:48:17 +01:00
8185a77697 Document v1.1.10 session history in CLAUDE.md
Added comprehensive Session 12 documentation covering:
- Two critical bug fixes (admin tabs + frontend empty state)
- Root cause analysis for both issues
- CSS panel hiding solution
- Twig empty state conditional
- Translation updates for all 6 locales
- Key lessons learned about CSS timing and empty states
- Debugging approach and testing recommendations

Fixed markdown linting warnings (MD036, MD032).

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:43:37 +01:00
6c2e317230 Add release package v1.1.10 with checksums
Critical bug fixes for admin and frontend issues discovered after v1.1.9.

Package: wc-composable-product-v1.1.10.zip (413 KB, 379 files)
SHA-256: 63bfe97aa9fd98e74750786ed0e1579b069505e85558316f7042787994c856ac
MD5: 271aad47684ee8318a8824861d5fc387

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:40:45 +01:00
58f5329bc4 Bump version to 1.1.10 - Fix admin and frontend critical bugs
Two critical bug fixes after v1.1.9 release:
1. Admin tabs both visible on initial page load
2. Frontend product selector showing no products

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:38:42 +01:00
0767016370 Update translations with new empty state message
Added translation for "No products available for selection" message in all 6 locales:
- de_DE (formal): Keine Produkte zur Auswahl verfügbar. Bitte konfigurieren Sie...
- de_DE_informal: ...Bitte konfiguriere...
- de_CH (formal): ...Bitte konfigurieren Sie...
- de_CH_informal: ...Bitte konfiguriere...
- fr_CH: Aucun produit disponible pour la sélection...
- it_CH: Nessun prodotto disponibile per la selezione...

Recompiled all .mo files.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:37:51 +01:00
fa7ec0e422 Fix two critical bugs in v1.1.9
Bug 1: Admin - Both General and Composable tabs visible on initial load
- Added explicit display:none to #composable_product_data panel
- Panel now hidden by default, shows only when product-type-composable class is present
- Prevents both tabs showing simultaneously on new product creation

Bug 2: Frontend - No feedback when no products configured
- Added empty state message when products array is empty
- Users now see helpful message instead of blank grid
- Cleared Twig cache to ensure template changes take effect

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:34:46 +01:00
f4d2543d4e Add release package v1.1.9 with checksums
Critical bug fix release - Admin rendering completely broken in v1.1.8.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:22:54 +01:00
9e4513f911 Bump version to 1.1.9 - Fix critical admin rendering bug
Fix overly broad CSS selectors that broke admin tabs in v1.1.8.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:21:30 +01:00
4dc7b767a8 Fix admin CSS - tabs disappeared due to overly aggressive selectors
CRITICAL FIX: The previous CSS change used .show_if_composable with !important
which hid ALL elements with that class, including the tab links themselves.

Changes:
- Changed from .show_if_composable to .options_group.show_if_composable
- Changed from .product_data_tabs .composable_options to li.composable_options
- Removed !important flags (not needed with specific selectors)
- Now only hides the general tab option groups, not the tab links

This fixes:
- Missing Composable Options tab in product edit screen
- Fields appearing out of context
- Tab navigation completely broken

The issue was that WooCommerce adds 'show_if_composable' class to BOTH:
1. The tab link (li.composable_options.show_if_composable)
2. The general tab fields (div.options_group.show_if_composable)

Now we specifically target only the option groups, leaving tabs alone.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:16:37 +01:00
f763e35d19 Add release package v1.1.8 with checksums
Package details:
- Size: 411 KB (421,220 bytes)
- Files: 376 (all source + vendor + translations + .mo files)
- Directory structure: wc-composable-product/ (WordPress standard)
- SHA-256: d7d06e2a5d336609249f803b681cdf270dbe60d6fc28bdd6c451c6744d2fdab6
- MD5: 78eee5eee4762c308c5d37d1aac06b04

Release v1.1.8 includes:
- Critical admin rendering bug fix (tab visibility)
- Critical frontend product selector fix (WooCommerce button hiding)
- Critical price localization fix (wc_price integration)

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:13:59 +01:00
8b271c90c0 Merge branch 'dev' 2025-12-31 22:12:50 +01:00
0dd4408b23 Bump version to 1.1.8 for release
Version 1.1.8 includes critical UI bug fixes:
- Admin rendering bug (tab visibility)
- Frontend product selector not appearing
- Price formatting localization

Updated CHANGELOG.md with comprehensive v1.1.8 release notes.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:12:43 +01:00
7a4a0a0135 Document v1.1.8 bug fixes in session history
Added comprehensive documentation for Session 11 covering three critical UI bug fixes:

1. Admin rendering bug - Fixed CSS specificity for proper tab visibility
2. Frontend product selector not appearing - Added woocommerce_is_purchasable filter
3. Localized price formatting - Implemented full WooCommerce price format support

Documentation includes:
- Detailed root cause analysis for each bug
- Complete code examples showing the fixes
- Links to specific file locations and line numbers
- Key lessons learned about WordPress/WooCommerce integration
- Testing recommendations for verification

Updated "Bugs found" section to mark all three issues as fixed in v1.1.8.

Added note about v1.1.6/v1.1.7 package structure fix (parent directory issue).

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:10:01 +01:00
c6a48d6404 Fix critical UI bugs in admin and frontend
Fixes three critical bugs reported in CLAUDE.md:

1. Admin rendering bug - Fixed CSS to prevent both General and Composable
   Options tabs from showing simultaneously on initial page load
   - Enhanced CSS specificity with !important flags
   - Added body.product-type-composable selectors for proper visibility control
   - Hides Composable Options tab by default, shows only when composable type selected

2. Frontend product selector not appearing - Fixed WooCommerce integration
   - Added hide_default_add_to_cart() method to Cart_Handler
   - Hooks woocommerce_is_purchasable filter to return false for composable products
   - This hides WooCommerce's default add-to-cart button
   - Allows our custom product selector to be the only interface

3. Localized price formatting - Implemented proper WooCommerce price formatting
   - Added wc_price Twig function in Plugin.php
   - Updated Product_Selector to pass formatted price HTML to template
   - Added price_format data to JavaScript localization
   - Implemented formatPrice() method in frontend.js
   - Supports all WooCommerce price formats (currency position, decimals, separators)
   - Template now uses {{ fixed_price_html|raw }} and {{ zero_price_html|raw }}
   - JavaScript dynamically formats prices using locale-specific settings

Technical improvements:
- Cart_Handler.php: +14 lines (hide_default_add_to_cart method)
- Plugin.php: +7 lines (wc_price function, price format localization)
- Product_Selector.php: +2 lines (formatted price HTML context)
- templates/product-selector.twig: Modified to use formatted price HTML
- assets/css/admin.css: +24 lines (enhanced tab visibility control)
- assets/js/frontend.js: +28 lines (formatPrice method with WooCommerce format support)

All PHP files pass lint checks. Frontend now properly displays localized prices
with correct currency symbols, decimal separators, and thousand separators for
all WooCommerce-supported locales (CHF for Switzerland, € for Europe, etc.).

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:08:08 +01:00
ac1cb9b135 Merge dev to main with corrected v1.1.6 package structure
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:00:19 +01:00
f5bc0d0335 Fix v1.1.6 release package structure for WordPress compatibility
Corrected directory structure to match WordPress plugin standards.
Package now contains wc-composable-product/ parent directory with all files inside.
WordPress will extract to wp-content/plugins/wc-composable-product/ (correct!).

Package size: 410 KB (419,430 bytes)
New SHA-256: fb8f12486f19aef61f6e6ea4af63fe66f64adca66e2d42e1d17e9f05cb82f39f
New MD5: cc8c13780c4e8063c97b8632d0a43adb

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 21:57:49 +01:00
88a907c4dd Fix v1.1.7 release package structure for WordPress compatibility
CRITICAL FIX: WordPress plugin directory structure

Previous issue:
- ZIP contained files at root level
- WordPress created directory based on ZIP name: wc-composable-product-v1.1.7/
- This caused version-numbered directory in wp-content/plugins/

Corrected structure:
- ZIP now contains wc-composable-product/ parent directory
- All plugin files inside wc-composable-product/ directory
- WordPress extracts to wp-content/plugins/wc-composable-product/ (correct!)

Changes:
- Recreated ZIP with proper directory structure using rsync + zip
- Package size: 410 KB (419,697 bytes) - slightly larger due to parent dir
- New SHA-256: 866e7dd34431f4c881629fd8b59ddd3a27c7a45b7324a3d88cd064a3e01c1b83
- New MD5: 871fbb3b910380c0e43bcf1538408eda

WordPress standard: Plugin ZIP must contain single parent directory named after
the plugin slug, with all files inside that directory.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 21:56:49 +01:00
03a7624564 Update CLAUDE.md with release package commit information
Added post-release updates section to v1.1.7 documentation:
- Both v1.1.6 and v1.1.7 release packages now committed to repository
- v1.1.6: 378 KB with .po files only (translations won't work)
- v1.1.7: 393 KB with .po + .mo files (translations functional)
- All packages include SHA-256 and MD5 checksums

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 21:50:54 +01:00
1c3f44f3c2 Add release package v1.1.6 with checksums
Release package for v1.1.6 including:
- Complete admin translations for Fixed Price field (v1.1.4 feature)
- All 6 locales with 56/56 strings translated (.po files)
- Package size: 378 KB (1,092,772 bytes)
- Files included: 370 files

Checksums:
- SHA-256: d64f4f5f1a00d392989cb613780e5726106a08c6aace08e0c74c80553a0b0f1e
- MD5: eae384e342450abd4ac83af0266ac764

Note: This version includes .po translation files but not compiled .mo files.
Users should upgrade to v1.1.7 for functional translations in WordPress.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 21:48:47 +01:00
287f8b778b Add release package v1.1.7 with checksums
Release package for v1.1.7 including:
- Compiled .mo translation files for all 6 locales
- Critical fix: Translations now display in WordPress admin
- Package size: 393 KB (402,351 bytes)
- Files included: 376 files

Checksums:
- SHA-256: 518d411c8a35fff26f6cd07dd7548dd46dfc2d8452ce3735b96e10cd582bf3fc
- MD5: 2eb25087a470ff2cf7d36490ea34eed9

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 21:46:28 +01:00
63d8f9ed52 Document v1.1.7 release in CLAUDE.md session history
Added comprehensive documentation for Session 10:
- Critical bug fix: Missing translations due to lack of compiled .mo files
- Root cause analysis: WordPress requires .mo files, not just .po files
- Solution: Compiled all 6 .po files to .mo format using msgfmt
- Release details: v1.1.7 with 393 KB package, 376 files
- Key lessons: .po vs .mo files, WordPress i18n requirements, testing workflow

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 21:45:14 +01:00
601570d724 Bump version to 1.1.7 for release
- Version 1.1.7 includes compiled .mo translation files
- Critical fix: Translations now display in WordPress admin
- All 6 locales (de_DE, de_DE_informal, de_CH, de_CH_informal, fr_CH, it_CH) fully functional

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 21:35:53 +01:00
e9b2d1c79b Add compiled .mo translation files for all locales
- Compiled 6 .mo files from .po sources (de_DE, de_DE_informal, de_CH, de_CH_informal, fr_CH, it_CH)
- Required for WordPress to load translations in admin and frontend
- All locales now have 56/56 strings translated and compiled

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 21:33:44 +01:00
d27dd4b7bd Document v1.1.6 release in CLAUDE.md
Added comprehensive session history for v1.1.6 including:
- Translation completion for all 6 locales
- Version bump details
- Release package creation
- Checksums and file counts
- Key lessons learned about translation maintenance

Fixed markdown linting: Added blank line before list

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 21:20:22 +01:00
1b7c7a0257 Bump version to 1.1.6 for release
Incremented version number to 1.1.6 reflecting admin translation updates.

Changes:
- Version header: 1.1.5 → 1.1.6
- Version constant: 1.1.5 → 1.1.6
- CHANGELOG.md: Added v1.1.6 release notes

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 21:16:43 +01:00
4f65c8e5e0 Add missing admin translations for Fixed Price field
Updated all translation files with new strings from v1.1.4:
- Simplified "How to calculate the price" description
- New "Fixed Price" field label
- New "Enter the fixed price for this composable product" description

Translations added to all 6 locales:
- de_DE (German formal): Festpreis / Geben Sie den Festpreis ein
- de_DE_informal (German informal): Festpreis / Gib den Festpreis ein
- de_CH (Swiss German formal): Festpreis / Geben Sie den Festpreis ein
- de_CH_informal (Swiss German informal): Festpreis / Gib den Festpreis ein
- fr_CH (Swiss French): Prix fixe / Entrez le prix fixe
- it_CH (Swiss Italian): Prezzo fisso / Inserisci il prezzo fisso

All admin strings are now fully translated across all supported locales.

Updated CLAUDE.md "Bugs found" section to mark admin translation task as completed.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 21:12:46 +01:00
054617f320 Document v1.1.5 Twig filter bug fix in CLAUDE.md
Added comprehensive session history for v1.1.5 including:
- Root cause analysis of Twig filter vs function mismatch
- Error log evidence and backtrace analysis
- Technical solution with code examples
- Lessons learned about multi-plugin Twig compatibility
- Updated "Bugs found" section marking Twig bug as fixed

Also fixed markdown linting warnings:
- Added blank line before fenced code block
- Added language specification (text) to code fence
- Added blank line around list

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 21:07:20 +01:00
8fc0614334 Fix critical Twig filter error in product selector template
Fixed "Unknown 'esc_attr' filter" error that occurred when rendering
the product selector template. The issue was caused by WordPress
escaping functions being registered only as Twig functions, not filters.

Changes:
- Added TwigFilter registrations for esc_html, esc_attr, esc_url
- Template now supports both filter syntax (|esc_attr) and function syntax
- Fixes compatibility issues when other plugins use their own Twig instances
- Version bump to 1.1.5

This resolves the bug documented in logs/fatal-errors-2025-12-31.log

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 21:06:08 +01:00
867abc8f63 Document v1.1.4 session: Fixed price field enhancement
Added session history for v1.1.4 which introduced:
- Fixed price field in Composable Options tab
- JavaScript toggle based on pricing mode selection
- Improved admin UX with progressive disclosure

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 21:01:52 +01:00
818fd51502 Document translation updates in CLAUDE.md v1.1.3 section 2025-12-31 17:36:54 +01:00
392559dedc Update all translation files with missing stock-related strings
Added 8 missing stock management translations to all locales:
- de_DE (German, formal): Stock strings with "auf Lager"
- de_DE_informal (German, informal): Stock strings with "auf Lager"
- de_CH (Swiss German, formal): Stock strings with "an Lager"
- de_CH_informal (Swiss German, informal): Stock strings with "an Lager"
- fr_CH (Swiss French): Stock strings with "en stock/rupture"

All translation files now complete with 55/55 strings:
- "\"%s\" is out of stock and cannot be selected."
- "Only %2$d of \"%1$s\" are available in stock."
- "Stock reduced for \"%1$s\": -%2$d (remaining: %3$d)"
- "Stock restored for \"%1$s\": +%2$d (total: %3$d)"
- "Out of stock"
- "Only"
- "left"
- "In stock"

Note: it_CH already had complete translations from v1.1.0

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 17:36:13 +01:00
17d5312df3 Add releases/ directory to project structure in CLAUDE.md 2025-12-31 17:27:18 +01:00
037be97ece Update CLAUDE.md with v1.1.3 session history
Session 6 documented:
- WooCommerce HPOS compatibility implementation
- Price calculation conflict resolution
- Compatibility with WooCommerce Analytics and pricing plugins
- User confirmation: "it all works, now"

Key learnings:
- HPOS declaration is critical for modern WooCommerce
- Static flags prevent duplicate hook execution
- Cart item metadata flags for plugin cooperation
- Compatibility testing with common WC extensions

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 17:26:21 +01:00
28d2223306 Add release package v1.1.3 with checksums
Release v1.1.3 - WooCommerce HPOS compatibility and pricing fixes

Package contents:
- Complete plugin source code
- Vendor dependencies (Twig)
- Translation files
- Documentation
- Assets (CSS/JS)

Checksums:
- SHA-256: 0ca23ca12570f0e9c518514ffc5209d78c76c3295954d10ec74a28013a762956
- MD5 also included for verification

This release addresses WooCommerce compatibility warnings and prevents
conflicts with WooCommerce Analytics, Update Manager, and third-party
pricing plugins like WooCommerce Tier and Package Prices.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 17:18:48 +01:00
413b5d8acd Add WooCommerce HPOS compatibility and fix pricing conflicts (v1.1.3)
Fixes WooCommerce compatibility warnings reported by user.

WooCommerce HPOS compatibility:
- Added before_woocommerce_init hook to declare HPOS compatibility
- Declares compatibility with custom_order_tables feature
- Ensures plugin works with WooCommerce's modern order storage

Price calculation improvements:
- Added static flag to prevent multiple executions
- Added composable_price_calculated flag to cart items
- Prevents conflicts with third-party pricing plugins
- Stops other plugins from re-calculating composable product prices

This resolves incompatibility warnings with:
- WooCommerce Analytics
- WooCommerce Update Manager
- Third-party pricing extensions

Files modified:
- wc-composable-product.php: Version 1.1.3, HPOS declaration
- includes/Cart_Handler.php: Improved price calculation guards
- CHANGELOG.md: Documented changes

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 17:11:29 +01:00
8aaf30de99 Update CLAUDE.md with v1.1.1 and v1.1.2 session history
Document the critical bug fix journey for the WC_Settings_Page error:

v1.1.1 session (failed attempt):
- Attempted to fix with hook timing change
- Changed to woocommerce_init hook
- Bug persisted - error logs showed it still failed
- Lesson: Always verify fixes with error logs

v1.1.2 session (successful fix):
- Discovered root cause: Settings.php loaded too early
- require_once happened during Plugin::includes()
- PHP tried to parse 'extends WC_Settings_Page' before class existed
- Solution: Delayed require_once to add_settings_page() callback
- This callback runs when WC has loaded all settings classes

Key learnings documented:
1. Class loading order matters more than hook timing
2. Always verify fixes don't just assume they work
3. Lazy loading pattern for extending third-party classes
4. Read error logs thoroughly - backtrace reveals the sequence
5. Don't assume hook order means all classes are loaded
6. Test immediately after each release

Also documents the debugging approach that worked and the
5-version journey to finally fix this persistent issue.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 17:03:11 +01:00
18d340d029 Add release package v1.1.2 with checksums
Release v1.1.2 - CRITICAL bug fix for Settings.php class loading

This release fixes the persistent WC_Settings_Page error that affected all previous versions including v1.1.1.

Root cause:
- Settings.php extends WC_Settings_Page
- File was being required during Plugin::includes()
- WC_Settings_Page class didn't exist at that point
- Hook timing changes (v1.0.1, v1.1.1) were insufficient

Solution implemented:
- Removed require_once from Plugin::includes()
- Moved to Plugin::add_settings_page() callback
- Loads on-demand via woocommerce_get_settings_pages filter
- WC_Settings_Page guaranteed to exist at that point

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

Package size: 383 KB
SHA-256: 191eae035b34ce8b33b90cf9d85ed54e493c1b471cda0efe5c992a512e91cc36

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 17:01:38 +01:00
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
62 changed files with 1873 additions and 41 deletions

4
.gitignore vendored
View File

@@ -1,6 +1,7 @@
# Linked sources
wp-core
wp-plugins
tpp
# Editor swap files
*.*swp
@@ -21,6 +22,3 @@ cache/
.DS_Store
Thumbs.db
# Release files
*.zip
releases/

View File

@@ -5,6 +5,327 @@ 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/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.1.13] - 2025-12-31
### Fixed
- **CRITICAL**: "No products available for selection" message showing even when products are configured
- Removed overly strict `is_in_stock()` requirement that was filtering out all products
- Products now show regardless of stock status (out-of-stock items are displayed but disabled)
- Added `'relation' => 'AND'` to meta_query for proper handling of multiple meta conditions
### Changed
- Product retrieval now shows all purchasable products, not just in-stock ones
- Stock status still displayed on frontend with appropriate styling
- Out-of-stock items shown but disabled via checkbox and visual indicators
- Frontend stock management from v1.1.0 still fully functional
### Technical
- Modified file: includes/Product_Type.php (lines 117-124, 177, 181)
- Changed from `$variation->is_in_stock() && $variation->is_purchasable()` to just `$variation->is_purchasable()`
- Changed from `$product->is_in_stock() && $product->is_purchasable()` to just `$product->is_purchasable()`
- Added `'relation' => 'AND'` to meta_query array for WordPress query compatibility
### Notes
- This fixes the issue where NO products were showing in the selector
- Stock validation still occurs at add-to-cart time (Stock_Manager class)
- Frontend still displays stock badges (in stock, low stock, out of stock)
- Out-of-stock items remain non-selectable via disabled checkboxes
- All translation files remain at 100% completion (57/57 strings)
## [1.1.12] - 2025-12-31
### Fixed
- **CRITICAL**: Variable product variations still not appearing in product selector after v1.1.11 release
- Changed variation retrieval method from `get_available_variations()` to `get_children()` for more reliable variation ID retrieval
- `get_available_variations()` returns complex data arrays which may not work in all contexts
- `get_children()` returns simple array of variation IDs directly, ensuring consistent results
### Technical
- Modified file: includes/Product_Type.php (lines 171-184)
- Changed from `$product->get_available_variations()` to `$product->get_children()`
- More direct and reliable method for retrieving variation IDs
- Each variation ID passed to `wc_get_product()` for full product object
- Maintains all stock and purchasability checks from v1.1.11
### Notes
- This is a patch release fixing the variable product support introduced in v1.1.11
- User reported "nope, still no product selectable" after v1.1.11
- Root cause: `get_available_variations()` returns variation data arrays instead of clean IDs
- `get_children()` is the standard WooCommerce method for retrieving variation IDs
- All translation files remain at 100% completion (57/57 strings - no changes needed)
## [1.1.11] - 2025-12-31
### Added
- **FEATURE**: Variable product support - composable products can now include variable products and their variations
- Variable products automatically expand to show all available variations as selectable items
- Each variation displays with full attribute information (e.g., "Product - Color: Red, Size: Large")
### Fixed
- Products not showing in selector when all available products were variable products
- Variable products were being filtered out because parent products aren't directly purchasable
### Changed
- Modified `get_available_products()` to detect and handle variable products
- Variable products now expand into their individual variations
- Each variation checked individually for stock status and purchasability
- Simple products continue to work exactly as before
### Technical
- Modified file: includes/Product_Type.php (lines 160-188)
- Added logic to detect `is_type('variable')` products
- Uses `get_available_variations()` to retrieve all variations
- Each variation validated with `is_in_stock()` and `is_purchasable()`
- Maintains backward compatibility with simple products
### Notes
- This is a feature enhancement release, not a bug fix
- Resolves the issue where categories containing only variable products showed no selections
- Variations display with their parent product name plus selected attributes
- Stock management works correctly for both simple products and variations
- All translation files remain at 100% completion (57/57 strings - no new strings added)
## [1.1.10] - 2025-12-31
### Fixed
- **CRITICAL**: Admin panel - Both General and Composable tabs visible simultaneously on initial page load
- **CRITICAL**: Frontend - No products showing in product selector, only cart button and pricing visible
- Empty product grid now shows helpful message instead of blank space
### Changed
- Added explicit `display: none` to `#composable_product_data` panel for proper initial hiding
- Panel now only shows when `body.product-type-composable` class is present
- Added empty state message in product selector template when no products are configured
- Cleared Twig cache to ensure template changes take effect
### Added
- Empty state message: "No products available for selection. Please configure the product criteria in the admin panel."
- Translations for empty state message in all 6 supported locales (de_DE, de_DE_informal, de_CH, de_CH_informal, fr_CH, it_CH)
- Recompiled .mo translation files
### Technical
- Modified files: assets/css/admin.css (lines 7-16), templates/product-selector.twig (lines 12-15)
- Root cause (admin): Panel lacked explicit CSS hiding rule, relied only on `hidden` class
- Root cause (frontend): No feedback when products array is empty
- Solution: CSS specificity + empty state conditional in Twig template
### Notes
- This release fixes two critical bugs discovered immediately after v1.1.9
- Admin interface now correctly hides composable panel until product type is selected
- Frontend provides clear user feedback when product selection is unavailable
- All translation files now 100% complete (57/57 strings)
## [1.1.9] - 2025-12-31
### Fixed
- **CRITICAL**: Admin rendering completely broken - tabs disappeared and fields appeared out of context after v1.1.8 release
- CSS selectors were too broad, hiding tab navigation along with field groups
- Removed `!important` flags that caused overly aggressive hiding
### Changed
- Made CSS selectors more specific: `.options_group.show_if_composable` for field groups only
- Added separate rule for tab links: `.product_data_tabs li.composable_options`
- Tab navigation now works correctly without hiding itself
### Technical
- Modified files: assets/css/admin.css (lines 22-40)
- Root cause: `.show_if_composable` class used by WooCommerce for both tab links AND field groups
- Solution: Separate selectors for each use case to prevent unintended hiding
### Notes
- This release fixes critical regression introduced in v1.1.8
- Admin interface now renders correctly with visible tabs and properly positioned fields
- No `!important` flags needed with specific selectors
## [1.1.8] - 2025-12-31
### Fixed
- **CRITICAL**: Admin rendering bug where both General and Composable Options tabs showed simultaneously on initial page load
- **CRITICAL**: Frontend product selector not appearing on product pages - WooCommerce's default add-to-cart button now hidden for composable products
- **CRITICAL**: Price formatting not localized - prices now display with proper currency symbols, decimal separators, and thousand separators for all locales
### Added
- `wc_price()` Twig function for proper price formatting in templates
- `formatPrice()` JavaScript method with full WooCommerce locale support
- Price format localization data passed to frontend JavaScript (decimal/thousand separators, currency position, number of decimals)
- `hide_default_add_to_cart()` method to prevent WooCommerce's default purchase UI for composable products
### Changed
- Enhanced CSS specificity with `!important` flags for proper tab visibility control
- Template now uses `{{ fixed_price_html|raw }}` instead of raw currency concatenation
- Product selector passes pre-formatted price HTML from `wc_price()` function
- Frontend JavaScript updates prices dynamically using WooCommerce format settings
### Technical
- Modified files: assets/css/admin.css (+24 lines), includes/Cart_Handler.php (+14 lines), includes/Plugin.php (+7 lines), includes/Product_Selector.php (+2 lines), templates/product-selector.twig, assets/js/frontend.js (+28 lines)
- All PHP files pass syntax validation
- Supports Swiss format (CHF 50.-), European format (50,00 €), US format ($50.00), and all other WooCommerce locales
- Thousand separator support: comma (1,000), dot (1.000), apostrophe (1'000), space (1 000)
### Notes
- This release fixes all three critical UI bugs reported in CLAUDE.md
- Admin tabs now display correctly on initial page load without JavaScript flicker
- Frontend product selector is now the only purchase interface (no WooCommerce default button)
- All prices maintain proper locale formatting during dynamic updates
## [1.1.7] - 2025-12-31
### Added
- Compiled .mo translation files for all 6 supported locales (de_DE, de_DE_informal, de_CH, de_CH_informal, fr_CH, it_CH)
- WordPress can now load translations in admin and frontend areas
### Fixed
- **CRITICAL**: Missing translations in WordPress admin when using non-English locales
- Settings page ("Composable Products", "Default Selection Limit", etc.) now properly translated
- Product settings ("Composable Options", "Selection Criteria", etc.) now properly translated
### Technical
- Compiled .mo files from .po sources using msgfmt
- All 6 locales now have complete translation coverage (56/56 strings translated and compiled)
- .mo files required for WordPress i18n system to display translations
### Notes
- Previous versions included .po translation files but WordPress requires compiled .mo files
- This release makes all existing translations actually visible to users
## [1.1.6] - 2025-12-31
### Added
- Complete translations for all admin area strings across all 6 supported locales
- "Fixed Price" field label and description translations
### Changed
- Updated translation template (.pot) to version 1.1.6
- Simplified "How to calculate the price" description text
### Technical
- All .po files now include translations for v1.1.4 admin strings
- 100% translation coverage maintained across all locales (56/56 strings)
- German formal/informal variants properly differentiated (Sie vs. du)
## [1.1.5] - 2025-12-31
### Fixed
- **CRITICAL**: Fixed Twig template error "Unknown 'esc_attr' filter" when rendering product selector
- Template compatibility issue when other plugins (e.g., WooCommerce Tier and Package Prices) use Twig
- WordPress escaping functions now properly registered as both Twig functions AND filters
### Technical
- Added `TwigFilter` registrations for `esc_html`, `esc_attr`, and `esc_url` in `Plugin::init_twig()`
- Template can now use both syntax styles: `{{ value|esc_attr }}` (filter) and `{{ esc_attr(value) }}` (function)
- Prevents conflicts when multiple plugins bundle their own Twig installations
### Notes
- Previous versions only registered escaping functions as Twig functions, not filters
- Template used filter syntax (`|esc_attr`) which failed when parsed by external Twig instances
- Fix ensures compatibility regardless of which Twig instance processes the template
## [1.1.4] - 2025-12-31
### Added
- Fixed price field in Composable Options tab for easier price configuration
- JavaScript toggle to show/hide fixed price field based on selected pricing mode
### Changed
- Simplified pricing mode description text in admin interface
- Fixed price field now appears dynamically when "Fixed" pricing mode is selected
### Technical
- Added `_regular_price` field with `composable_fixed_price_field` CSS class in `Product_Data.php`
- Implemented `toggleFixedPriceField()` JavaScript function in `assets/js/admin.js`
- Progressive disclosure pattern improves admin UX by showing relevant fields only
## [1.1.3] - 2024-12-31
### Added
- WooCommerce HPOS (High-Performance Order Storage) compatibility declaration
- Prevents duplicate price calculations to avoid conflicts with other pricing plugins
### Fixed
- WooCommerce compatibility warnings with Analytics and other WooCommerce extensions
- Price calculation conflicts with third-party pricing plugins
### Technical
- Added `before_woocommerce_init` hook to declare HPOS compatibility
- Implemented static flag in `Cart_Handler::calculate_cart_item_price()` to prevent multiple executions
- Added `composable_price_calculated` flag to cart items to prevent re-calculation by other plugins
- Ensures composable products work with WooCommerce's modern order storage system
## [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
### Added

1111
CLAUDE.md

File diff suppressed because it is too large Load Diff

View File

@@ -4,10 +4,17 @@
* @package WC_Composable_Product
*/
/* Hide composable panel by default */
#composable_product_data {
display: none;
padding: 12px;
}
/* Show composable panel when composable type is selected */
body.product-type-composable #composable_product_data {
display: block;
}
.composable_criteria_group {
border-top: 1px solid #eee;
padding-top: 12px;
@@ -19,11 +26,23 @@
min-height: 150px;
}
.show_if_composable {
/* Hide composable-specific elements by default (but not tabs) */
.options_group.show_if_composable {
display: none;
}
.product-type-composable .show_if_composable {
/* Show composable elements when composable product type is selected */
body.product-type-composable .options_group.show_if_composable {
display: block;
}
/* Hide the Composable Options tab link by default */
.product_data_tabs li.composable_options {
display: none;
}
/* Show the Composable Options tab when composable type selected */
body.product-type-composable .product_data_tabs li.composable_options {
display: block;
}

View File

@@ -36,6 +36,23 @@
$('#composable_criteria_' + criteriaType).show();
}).trigger('change');
/**
* Toggle fixed price field based on pricing mode
*/
function toggleFixedPriceField() {
const pricingMode = $('#_composable_pricing_mode').val();
const $fixedPriceField = $('.composable_fixed_price_field');
if (pricingMode === 'fixed') {
$fixedPriceField.show();
} else {
$fixedPriceField.hide();
}
}
$('#_composable_pricing_mode').on('change', toggleFixedPriceField);
toggleFixedPriceField();
/**
* Initialize enhanced select for categories and tags
*/

View File

@@ -63,6 +63,36 @@
this.clearMessages($container);
},
/**
* Format price using WooCommerce settings
*
* @param {number} price Price amount
* @return {string} Formatted price HTML
*/
formatPrice: function(price) {
if (typeof wcComposableProduct === 'undefined' || !wcComposableProduct.price_format) {
return price.toFixed(2);
}
const format = wcComposableProduct.price_format;
const decimals = parseInt(format.decimals, 10);
const decimalSep = format.decimal_separator;
const thousandSep = format.thousand_separator;
// Format number
let priceStr = price.toFixed(decimals);
const parts = priceStr.split('.');
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousandSep);
priceStr = parts.join(decimalSep);
// Apply price format (e.g., "%1$s%2$s" for symbol+price or "%2$s%1$s" for price+symbol)
let formatted = format.price_format
.replace('%1$s', '<span class="woocommerce-Price-currencySymbol">' + format.currency_symbol + '</span>')
.replace('%2$s', priceStr);
return '<span class="woocommerce-Price-amount amount">' + formatted + '</span>';
},
/**
* Update total price
*
@@ -79,8 +109,8 @@
}
});
const currencySymbol = $container.find('.total-price').data('currency');
$container.find('.calculated-total').text(currencySymbol + total.toFixed(2));
const formattedPrice = this.formatPrice(total);
$container.find('.calculated-total').html(formattedPrice);
},
/**

View File

@@ -63,7 +63,7 @@ class Product_Data {
woocommerce_wp_select([
'id' => '_composable_pricing_mode',
'label' => __('Pricing Mode', 'wc-composable-product'),
'description' => __('How to calculate the price. Leave empty to use global default.', 'wc-composable-product'),
'description' => __('How to calculate the price.', 'wc-composable-product'),
'desc_tip' => true,
'options' => [
'' => __('Use global default', 'wc-composable-product'),
@@ -72,6 +72,16 @@ class Product_Data {
],
]);
woocommerce_wp_text_input([
'id' => '_regular_price',
'label' => __('Fixed Price', 'wc-composable-product') . ' (' . get_woocommerce_currency_symbol() . ')',
'description' => __('Enter the fixed price for this composable product.', 'wc-composable-product'),
'desc_tip' => true,
'type' => 'text',
'data_type' => 'price',
'wrapper_class' => 'composable_fixed_price_field',
]);
echo '</div>';
}
}

View File

@@ -35,6 +35,21 @@ class Cart_Handler {
add_action('woocommerce_before_calculate_totals', [$this, 'calculate_cart_item_price']);
add_action('woocommerce_single_product_summary', [$this, 'render_product_selector'], 25);
add_action('woocommerce_checkout_create_order_line_item', [$this->stock_manager, 'store_selected_products_in_order'], 10, 3);
add_filter('woocommerce_is_purchasable', [$this, 'hide_default_add_to_cart'], 10, 2);
}
/**
* Hide default WooCommerce add to cart button for composable products
*
* @param bool $is_purchasable Is purchasable status
* @param \WC_Product $product Product object
* @return bool
*/
public function hide_default_add_to_cart($is_purchasable, $product) {
if ($product && $product->get_type() === 'composable') {
return false;
}
return $is_purchasable;
}
/**
@@ -185,14 +200,25 @@ class Cart_Handler {
return;
}
// Use static flag to prevent multiple executions
static $already_calculated = false;
if ($already_calculated) {
return;
}
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
if (isset($cart_item['data']) && $cart_item['data']->get_type() === 'composable') {
if (isset($cart_item['composable_products'])) {
if (isset($cart_item['composable_products']) && !isset($cart_item['composable_price_calculated'])) {
$product = $cart_item['data'];
$price = $product->calculate_composed_price($cart_item['composable_products']);
$cart_item['data']->set_price($price);
// Mark as calculated to prevent re-calculation by other plugins
$cart->cart_contents[$cart_item_key]['composable_price_calculated'] = true;
}
}
}
$already_calculated = true;
}
}

View File

@@ -84,13 +84,20 @@ class Plugin {
$this->twig->addFunction(new \Twig\TwigFunction('esc_html', 'esc_html'));
$this->twig->addFunction(new \Twig\TwigFunction('esc_attr', 'esc_attr'));
$this->twig->addFunction(new \Twig\TwigFunction('esc_url', 'esc_url'));
$this->twig->addFunction(new \Twig\TwigFunction('wc_price', 'wc_price'));
// Add WordPress escaping functions as Twig filters
$this->twig->addFilter(new \Twig\TwigFilter('esc_html', 'esc_html'));
$this->twig->addFilter(new \Twig\TwigFilter('esc_attr', 'esc_attr'));
$this->twig->addFilter(new \Twig\TwigFilter('esc_url', 'esc_url'));
}
/**
* Include required files
*/
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/Product_Type.php';
require_once WC_COMPOSABLE_PRODUCT_PATH . 'includes/Stock_Manager.php';
@@ -155,6 +162,13 @@ class Plugin {
'max_items' => __('Maximum items selected', 'wc-composable-product'),
'min_items' => __('Please select at least one item', 'wc-composable-product'),
],
'price_format' => [
'currency_symbol' => get_woocommerce_currency_symbol(),
'decimal_separator' => wc_get_price_decimal_separator(),
'thousand_separator' => wc_get_price_thousand_separator(),
'decimals' => wc_get_price_decimals(),
'price_format' => get_woocommerce_price_format(),
],
]);
}
}
@@ -191,6 +205,8 @@ class Plugin {
* @return array
*/
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();
return $settings;
}

View File

@@ -65,6 +65,8 @@ class Product_Selector {
'show_prices' => $show_prices,
'show_total' => $show_total,
'fixed_price' => $product->get_price(),
'fixed_price_html' => wc_price($product->get_price()),
'zero_price_html' => wc_price(0),
'currency_symbol' => get_woocommerce_currency_symbol(),
];

View File

@@ -115,6 +115,7 @@ class Product_Type extends \WC_Product {
// Exclude composable products from selection
$args['meta_query'] = [
'relation' => 'AND',
[
'key' => '_product_type',
'value' => 'composable',
@@ -163,7 +164,23 @@ class Product_Type extends \WC_Product {
if ($query->have_posts()) {
foreach ($query->posts as $post) {
$product = wc_get_product($post->ID);
if ($product && $product->is_in_stock() && $product->is_purchasable()) {
if (!$product) {
continue;
}
// Handle variable products by including their variations
if ($product->is_type('variable')) {
// Get variation IDs directly from the product
$variation_ids = $product->get_children();
foreach ($variation_ids as $variation_id) {
$variation = wc_get_product($variation_id);
if ($variation && $variation->is_purchasable()) {
$products[] = $variation;
}
}
} elseif ($product->is_purchasable()) {
// Simple and other product types
$products[] = $product;
}
}

Binary file not shown.

View File

@@ -144,8 +144,16 @@ msgid "Pricing Mode"
msgstr "Preismodus"
#: includes/Admin/Product_Data.php
msgid "How to calculate the price. Leave empty to use global default."
msgstr "Wie der Preis berechnet wird. Leer lassen, um den globalen Standard zu verwenden."
msgid "How to calculate the price."
msgstr "Wie der Preis berechnet wird."
#: includes/Admin/Product_Data.php
msgid "Fixed Price"
msgstr "Festpreis"
#: includes/Admin/Product_Data.php
msgid "Enter the fixed price for this composable product."
msgstr "Geben Sie den Festpreis für dieses zusammenstellbare Produkt ein."
#: includes/Admin/Product_Data.php
msgid "Use global default"
@@ -198,3 +206,39 @@ msgstr "Geben Sie Produkt-Artikelnummern durch Kommas getrennt ein."
#: includes/Admin/Product_Data.php
msgid "SKU-1, SKU-2, SKU-3"
msgstr "ART-1, ART-2, ART-3"
#: includes/Stock_Manager.php
msgid "\"%s\" is out of stock and cannot be selected."
msgstr "\"%s\" ist nicht an Lager und kann nicht ausgewählt werden."
#: includes/Stock_Manager.php
msgid "Only %2$d of \"%1$s\" are available in stock."
msgstr "Nur %2$d von \"%1$s\" sind an Lager verfügbar."
#: includes/Stock_Manager.php
msgid "Stock reduced for \"%1$s\": -%2$d (remaining: %3$d)"
msgstr "Lagerbestand reduziert für \"%1$s\": -%2$d (verbleibend: %3$d)"
#: includes/Stock_Manager.php
msgid "Stock restored for \"%1$s\": +%2$d (total: %3$d)"
msgstr "Lagerbestand wiederhergestellt für \"%1$s\": +%2$d (gesamt: %3$d)"
#: templates/product-selector.twig
msgid "Out of stock"
msgstr "Nicht an Lager"
#: templates/product-selector.twig
msgid "Only"
msgstr "Nur"
#: templates/product-selector.twig
msgid "left"
msgstr "übrig"
#: templates/product-selector.twig
msgid "In stock"
msgstr "An Lager"
#: templates/product-selector.twig
msgid "No products available for selection. Please configure the product criteria in the admin panel."
msgstr "Keine Produkte zur Auswahl verfügbar. Bitte konfigurieren Sie die Produktkriterien im Admin-Bereich."

Binary file not shown.

View File

@@ -144,8 +144,16 @@ msgid "Pricing Mode"
msgstr "Preismodus"
#: includes/Admin/Product_Data.php
msgid "How to calculate the price. Leave empty to use global default."
msgstr "Wie der Preis berechnet wird. Leer lassen, um den globalen Standard zu verwenden."
msgid "How to calculate the price."
msgstr "Wie der Preis berechnet wird."
#: includes/Admin/Product_Data.php
msgid "Fixed Price"
msgstr "Festpreis"
#: includes/Admin/Product_Data.php
msgid "Enter the fixed price for this composable product."
msgstr "Gib den Festpreis für dieses zusammenstellbare Produkt ein."
#: includes/Admin/Product_Data.php
msgid "Use global default"
@@ -198,3 +206,39 @@ msgstr "Gib Produkt-Artikelnummern durch Kommas getrennt ein."
#: includes/Admin/Product_Data.php
msgid "SKU-1, SKU-2, SKU-3"
msgstr "ART-1, ART-2, ART-3"
#: includes/Stock_Manager.php
msgid "\"%s\" is out of stock and cannot be selected."
msgstr "\"%s\" ist nicht an Lager und kann nicht ausgewählt werden."
#: includes/Stock_Manager.php
msgid "Only %2$d of \"%1$s\" are available in stock."
msgstr "Nur %2$d von \"%1$s\" sind an Lager verfügbar."
#: includes/Stock_Manager.php
msgid "Stock reduced for \"%1$s\": -%2$d (remaining: %3$d)"
msgstr "Lagerbestand reduziert für \"%1$s\": -%2$d (verbleibend: %3$d)"
#: includes/Stock_Manager.php
msgid "Stock restored for \"%1$s\": +%2$d (total: %3$d)"
msgstr "Lagerbestand wiederhergestellt für \"%1$s\": +%2$d (gesamt: %3$d)"
#: templates/product-selector.twig
msgid "Out of stock"
msgstr "Nicht an Lager"
#: templates/product-selector.twig
msgid "Only"
msgstr "Nur"
#: templates/product-selector.twig
msgid "left"
msgstr "übrig"
#: templates/product-selector.twig
msgid "In stock"
msgstr "An Lager"
#: templates/product-selector.twig
msgid "No products available for selection. Please configure the product criteria in the admin panel."
msgstr "Keine Produkte zur Auswahl verfügbar. Bitte konfiguriere die Produktkriterien im Admin-Bereich."

Binary file not shown.

View File

@@ -144,8 +144,16 @@ msgid "Pricing Mode"
msgstr "Preismodus"
#: includes/Admin/Product_Data.php
msgid "How to calculate the price. Leave empty to use global default."
msgstr "Wie der Preis berechnet wird. Leer lassen, um den globalen Standard zu verwenden."
msgid "How to calculate the price."
msgstr "Wie der Preis berechnet wird."
#: includes/Admin/Product_Data.php
msgid "Fixed Price"
msgstr "Festpreis"
#: includes/Admin/Product_Data.php
msgid "Enter the fixed price for this composable product."
msgstr "Geben Sie den Festpreis für dieses zusammenstellbare Produkt ein."
#: includes/Admin/Product_Data.php
msgid "Use global default"
@@ -198,3 +206,39 @@ msgstr "Geben Sie Produkt-Artikelnummern durch Kommas getrennt ein."
#: includes/Admin/Product_Data.php
msgid "SKU-1, SKU-2, SKU-3"
msgstr "ART-1, ART-2, ART-3"
#: includes/Stock_Manager.php
msgid "\"%s\" is out of stock and cannot be selected."
msgstr "\"%s\" ist nicht auf Lager und kann nicht ausgewählt werden."
#: includes/Stock_Manager.php
msgid "Only %2$d of \"%1$s\" are available in stock."
msgstr "Nur %2$d von \"%1$s\" sind auf Lager verfügbar."
#: includes/Stock_Manager.php
msgid "Stock reduced for \"%1$s\": -%2$d (remaining: %3$d)"
msgstr "Lagerbestand reduziert für \"%1$s\": -%2$d (verbleibend: %3$d)"
#: includes/Stock_Manager.php
msgid "Stock restored for \"%1$s\": +%2$d (total: %3$d)"
msgstr "Lagerbestand wiederhergestellt für \"%1$s\": +%2$d (gesamt: %3$d)"
#: templates/product-selector.twig
msgid "Out of stock"
msgstr "Nicht auf Lager"
#: templates/product-selector.twig
msgid "Only"
msgstr "Nur"
#: templates/product-selector.twig
msgid "left"
msgstr "übrig"
#: templates/product-selector.twig
msgid "In stock"
msgstr "Auf Lager"
#: templates/product-selector.twig
msgid "No products available for selection. Please configure the product criteria in the admin panel."
msgstr "Keine Produkte zur Auswahl verfügbar. Bitte konfigurieren Sie die Produktkriterien im Admin-Bereich."

Binary file not shown.

View File

@@ -144,8 +144,16 @@ msgid "Pricing Mode"
msgstr "Preismodus"
#: includes/Admin/Product_Data.php
msgid "How to calculate the price. Leave empty to use global default."
msgstr "Wie der Preis berechnet wird. Leer lassen, um den globalen Standard zu verwenden."
msgid "How to calculate the price."
msgstr "Wie der Preis berechnet wird."
#: includes/Admin/Product_Data.php
msgid "Fixed Price"
msgstr "Festpreis"
#: includes/Admin/Product_Data.php
msgid "Enter the fixed price for this composable product."
msgstr "Gib den Festpreis für dieses zusammenstellbare Produkt ein."
#: includes/Admin/Product_Data.php
msgid "Use global default"
@@ -198,3 +206,39 @@ msgstr "Gib Produkt-Artikelnummern durch Kommas getrennt ein."
#: includes/Admin/Product_Data.php
msgid "SKU-1, SKU-2, SKU-3"
msgstr "ART-1, ART-2, ART-3"
#: includes/Stock_Manager.php
msgid "\"%s\" is out of stock and cannot be selected."
msgstr "\"%s\" ist nicht auf Lager und kann nicht ausgewählt werden."
#: includes/Stock_Manager.php
msgid "Only %2$d of \"%1$s\" are available in stock."
msgstr "Nur %2$d von \"%1$s\" sind auf Lager verfügbar."
#: includes/Stock_Manager.php
msgid "Stock reduced for \"%1$s\": -%2$d (remaining: %3$d)"
msgstr "Lagerbestand reduziert für \"%1$s\": -%2$d (verbleibend: %3$d)"
#: includes/Stock_Manager.php
msgid "Stock restored for \"%1$s\": +%2$d (total: %3$d)"
msgstr "Lagerbestand wiederhergestellt für \"%1$s\": +%2$d (gesamt: %3$d)"
#: templates/product-selector.twig
msgid "Out of stock"
msgstr "Nicht auf Lager"
#: templates/product-selector.twig
msgid "Only"
msgstr "Nur"
#: templates/product-selector.twig
msgid "left"
msgstr "übrig"
#: templates/product-selector.twig
msgid "In stock"
msgstr "Auf Lager"
#: templates/product-selector.twig
msgid "No products available for selection. Please configure the product criteria in the admin panel."
msgstr "Keine Produkte zur Auswahl verfügbar. Bitte konfiguriere die Produktkriterien im Admin-Bereich."

Binary file not shown.

View File

@@ -144,8 +144,16 @@ msgid "Pricing Mode"
msgstr "Mode de tarification"
#: includes/Admin/Product_Data.php
msgid "How to calculate the price. Leave empty to use global default."
msgstr "Comment calculer le prix. Laisser vide pour utiliser la valeur par défaut globale."
msgid "How to calculate the price."
msgstr "Comment calculer le prix."
#: includes/Admin/Product_Data.php
msgid "Fixed Price"
msgstr "Prix fixe"
#: includes/Admin/Product_Data.php
msgid "Enter the fixed price for this composable product."
msgstr "Entrez le prix fixe pour ce produit composable."
#: includes/Admin/Product_Data.php
msgid "Use global default"
@@ -198,3 +206,39 @@ msgstr "Entrez les références des produits séparées par des virgules."
#: includes/Admin/Product_Data.php
msgid "SKU-1, SKU-2, SKU-3"
msgstr "REF-1, REF-2, REF-3"
#: includes/Stock_Manager.php
msgid "\"%s\" is out of stock and cannot be selected."
msgstr "\"%s\" est en rupture de stock et ne peut pas être sélectionné."
#: includes/Stock_Manager.php
msgid "Only %2$d of \"%1$s\" are available in stock."
msgstr "Seulement %2$d de \"%1$s\" sont disponibles en stock."
#: includes/Stock_Manager.php
msgid "Stock reduced for \"%1$s\": -%2$d (remaining: %3$d)"
msgstr "Stock réduit pour \"%1$s\": -%2$d (restant: %3$d)"
#: includes/Stock_Manager.php
msgid "Stock restored for \"%1$s\": +%2$d (total: %3$d)"
msgstr "Stock restauré pour \"%1$s\": +%2$d (total: %3$d)"
#: templates/product-selector.twig
msgid "Out of stock"
msgstr "Rupture de stock"
#: templates/product-selector.twig
msgid "Only"
msgstr "Seulement"
#: templates/product-selector.twig
msgid "left"
msgstr "restant"
#: templates/product-selector.twig
msgid "In stock"
msgstr "En stock"
#: templates/product-selector.twig
msgid "No products available for selection. Please configure the product criteria in the admin panel."
msgstr "Aucun produit disponible pour la sélection. Veuillez configurer les critères de produit dans le panneau d'administration."

Binary file not shown.

View File

@@ -144,8 +144,16 @@ msgid "Pricing Mode"
msgstr "Modalità di prezzo"
#: includes/Admin/Product_Data.php
msgid "How to calculate the price. Leave empty to use global default."
msgstr "Come calcolare il prezzo. Lasciare vuoto per utilizzare il valore predefinito globale."
msgid "How to calculate the price."
msgstr "Come calcolare il prezzo."
#: includes/Admin/Product_Data.php
msgid "Fixed Price"
msgstr "Prezzo fisso"
#: includes/Admin/Product_Data.php
msgid "Enter the fixed price for this composable product."
msgstr "Inserisci il prezzo fisso per questo prodotto componibile."
#: includes/Admin/Product_Data.php
msgid "Use global default"
@@ -230,3 +238,7 @@ msgstr "rimasti"
#: templates/product-selector.twig
msgid "In stock"
msgstr "Disponibile"
#: templates/product-selector.twig
msgid "No products available for selection. Please configure the product criteria in the admin panel."
msgstr "Nessun prodotto disponibile per la selezione. Si prega di configurare i criteri del prodotto nel pannello di amministrazione."

View File

@@ -2,7 +2,7 @@
# This file is distributed under the GPL v3 or later.
msgid ""
msgstr ""
"Project-Id-Version: WooCommerce Composable Products 1.0.0\n"
"Project-Id-Version: WooCommerce Composable Products 1.1.6\n"
"Report-Msgid-Bugs-To: https://github.com/magdev/wc-composable-product/issues\n"
"POT-Creation-Date: 2024-12-31 00:00+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
@@ -143,7 +143,15 @@ msgid "Pricing Mode"
msgstr ""
#: includes/Admin/Product_Data.php
msgid "How to calculate the price. Leave empty to use global default."
msgid "How to calculate the price."
msgstr ""
#: includes/Admin/Product_Data.php
msgid "Fixed Price"
msgstr ""
#: includes/Admin/Product_Data.php
msgid "Enter the fixed price for this composable product."
msgstr ""
#: includes/Admin/Product_Data.php
@@ -229,3 +237,7 @@ msgstr ""
#: templates/product-selector.twig
msgid "In stock"
msgstr ""
#: templates/product-selector.twig
msgid "No products available for selection. Please configure the product criteria in the admin panel."
msgstr ""

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

Binary file not shown.

View File

@@ -0,0 +1 @@
271aad47684ee8318a8824861d5fc387 wc-composable-product-v1.1.10.zip

View File

@@ -0,0 +1 @@
63bfe97aa9fd98e74750786ed0e1579b069505e85558316f7042787994c856ac wc-composable-product-v1.1.10.zip

Binary file not shown.

View File

@@ -0,0 +1 @@
63b105311dc1cc8ac67c05528ad02e30 wc-composable-product-v1.1.11.zip

View File

@@ -0,0 +1 @@
214002a28a0426b4d2423f234d1dff63e4a8e58c6301cbd6eaed8db670db88c6 wc-composable-product-v1.1.11.zip

Binary file not shown.

View File

@@ -0,0 +1 @@
546b9f9dd4ef0ec174d574af301a7bbc wc-composable-product-v1.1.12.zip

View File

@@ -0,0 +1 @@
c445f1744d28cb53ef314f2dbb253aae31a7750f49f615f5c11a109274736f75 wc-composable-product-v1.1.12.zip

Binary file not shown.

View File

@@ -0,0 +1 @@
37cef191778b448dcbd2ae10141f64c6 wc-composable-product-v1.1.2.zip

View File

@@ -0,0 +1 @@
191eae035b34ce8b33b90cf9d85ed54e493c1b471cda0efe5c992a512e91cc36 wc-composable-product-v1.1.2.zip

Binary file not shown.

View File

@@ -0,0 +1 @@
9bbed416019a796b4d4a5ef72e016e1f wc-composable-product-v1.1.3.zip

View File

@@ -0,0 +1 @@
0ca23ca12570f0e9c518514ffc5209d78c76c3295954d10ec74a28013a762956 wc-composable-product-v1.1.3.zip

Binary file not shown.

View File

@@ -0,0 +1 @@
eae384e342450abd4ac83af0266ac764 wc-composable-product-v1.1.6.zip

View File

@@ -0,0 +1 @@
d64f4f5f1a00d392989cb613780e5726106a08c6aace08e0c74c80553a0b0f1e wc-composable-product-v1.1.6.zip

Binary file not shown.

View File

@@ -0,0 +1 @@
871fbb3b910380c0e43bcf1538408eda releases/wc-composable-product-v1.1.7.zip

View File

@@ -0,0 +1 @@
866e7dd34431f4c881629fd8b59ddd3a27c7a45b7324a3d88cd064a3e01c1b83 releases/wc-composable-product-v1.1.7.zip

Binary file not shown.

View File

@@ -0,0 +1 @@
78eee5eee4762c308c5d37d1aac06b04 wc-composable-product-v1.1.8.zip

View File

@@ -0,0 +1 @@
d7d06e2a5d336609249f803b681cdf270dbe60d6fc28bdd6c451c6744d2fdab6 wc-composable-product-v1.1.8.zip

Binary file not shown.

View File

@@ -0,0 +1 @@
a5b08f3613d1b1e8aba0c2b7b82a1582 wc-composable-product-v1.1.9.zip

View File

@@ -0,0 +1 @@
f9fc497c0531c7ea828e164137f3db6e0a2755b899690dfb7d6411baf0c7a65a wc-composable-product-v1.1.9.zip

View File

@@ -9,6 +9,11 @@
</div>
<div class="composable-products-grid">
{% if products is empty %}
<div class="composable-no-products">
<p>{{ __('No products available for selection. Please configure the product criteria in the admin panel.') }}</p>
</div>
{% else %}
{% for product in products %}
<div class="composable-product-item{% if not product.in_stock %} out-of-stock{% endif %}" data-product-id="{{ product.id }}" data-price="{{ product.price }}" data-stock-status="{{ product.stock_status }}">
<div class="product-item-inner">
@@ -52,16 +57,17 @@
</div>
</div>
{% endfor %}
{% endif %}
</div>
{% if show_total %}
<div class="composable-total">
<div class="total-label">{{ __('Total Price:') }}</div>
<div class="total-price" data-currency="{{ currency_symbol }}">
<div class="total-price" data-currency="{{ currency_symbol }}" data-fixed-price="{{ fixed_price }}">
{% if pricing_mode == 'fixed' %}
{{ currency_symbol }}{{ fixed_price }}
{{ fixed_price_html|raw }}
{% else %}
<span class="calculated-total">{{ currency_symbol }}0.00</span>
<span class="calculated-total">{{ zero_price_html|raw }}</span>
{% endif %}
</div>
</div>

View File

@@ -3,7 +3,7 @@
* Plugin Name: WooCommerce Composable Products
* 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
* Version: 1.1.0
* Version: 1.1.13
* Author: Marco Graetsch
* Author URI: https://example.com
* License: GPL v3 or later
@@ -19,7 +19,7 @@
defined('ABSPATH') || exit;
// Define plugin constants
define('WC_COMPOSABLE_PRODUCT_VERSION', '1.1.0');
define('WC_COMPOSABLE_PRODUCT_VERSION', '1.1.13');
define('WC_COMPOSABLE_PRODUCT_FILE', __FILE__);
define('WC_COMPOSABLE_PRODUCT_PATH', plugin_dir_path(__FILE__));
define('WC_COMPOSABLE_PRODUCT_URL', plugin_dir_url(__FILE__));
@@ -61,8 +61,17 @@ function wc_composable_product_init() {
// Initialize main plugin class
WC_Composable_Product\Plugin::instance();
}
// Use woocommerce_loaded to ensure WooCommerce classes are available
add_action('woocommerce_loaded', 'wc_composable_product_init');
// Use woocommerce_init to ensure all WooCommerce classes including settings are loaded
add_action('woocommerce_init', 'wc_composable_product_init');
/**
* Declare HPOS compatibility
*/
add_action('before_woocommerce_init', function() {
if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) {
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true);
}
});
/**
* Activation hook