Added localhost/self-licensing license bypass and WordPress auto-update
integration from license server.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Zip follows symlinks, so vendor/magdev/wc-licensed-product-client/CLAUDE.md
was being included. Added exclusions for both lib/ and vendor/magdev/ paths.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The version field causes composer validate --strict to fail with a warning.
Version is determined by git tags instead.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update file structure in README.md and CLAUDE.md
- Document lib/ directory for git submodules
- Update submodule instructions with relative URL
- Add key learnings about vendor/ vs lib/ conflict
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move submodule from vendor/magdev/ to lib/ to avoid Composer conflicts
- Use relative submodule URL (../wc-licensed-product-client.git)
- Pin submodule to v0.2.2 tag
- Update composer.json with ^0.2 version constraint
- Simplify .gitignore (no vendor exceptions needed)
- Update workflow to exclude lib/.git instead of vendor/.git
Based on working wp-fedistream implementation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- README: Update automated releases section with submodule info
- README: Update file structure with .gitea/workflows and submodule
- README: Add v1.4.0 changelog entry
- CLAUDE.md: Update version to 1.4.0, roadmap to 1.4.1
- CLAUDE.md: Rewrite release process for CI/CD workflow
- CLAUDE.md: Add git submodule documentation
- CLAUDE.md: Add v1.4.0 session history
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Bundle magdev/wc-licensed-product-client as git submodule
- Update composer.json to use path repository instead of VCS
- Update .gitignore to allow submodule in vendor directory
- Update CI workflow to checkout submodules recursively
- Remove private repository authentication step (no longer needed)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Automated release workflow triggered on version tags (v*)
- Validates plugin version matches tag
- Installs production Composer dependencies
- Compiles translation files
- Creates release package with proper exclusions
- Generates SHA256 checksum
- Publishes release to Gitea with changelog notes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create automated release workflow triggered on version tags (v*)
- Validates plugin version matches tag version
- Installs production dependencies via Composer
- Compiles translation files (.po to .mo)
- Builds release package with proper exclusions
- Generates SHA256 checksum
- Publishes release to Gitea with changelog notes
- Document automated release process in README
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update version to 1.3.1 and date to 2026-01-27
- Replace completed v1.3.1 roadmap with v1.3.2 placeholder
- Update license client dependency to dev-main
- Add v1.3.1 session history documenting SecureLicenseClient switch
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Added license management feature to admin features list
- Updated PHP requirement from 7.4 to 8.3
- Updated file structure version comment to v1.3.1
- Added v1.3.0 and v1.3.1 changelog entries
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Upgraded from LicenseClient to SecureLicenseClient with HMAC-SHA256 response signature verification
- Added Server Secret configuration field for secure communication
- Added rate limit exception handling with retry time display
- Added signature verification error handling
- Added URL validation error handling (SSRF protection)
- Updated all translation files with new strings
- Compiled .mo files for all 7 language variants
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Updated PHP requirement from 7.4 to 8.3 in compatibility notes
- Added Session History section documenting v1.3.0 release session
- Documented key learnings about license client integration
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Breaking Changes:
- PHP 8.3+ now required (previously 7.4+)
Added:
- License management integration using magdev/wc-licensed-product-client
- Settings page split into General and License sub-tabs
- License validation and activation via AJAX
- PHP version check with admin notice
Changed:
- Refactored settings class to use modern WooCommerce patterns
- Updated all translations with new license-related strings
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added three new critical sections documenting lessons learned during v1.2.9 development:
1. WordPress Translation Functions with printf
- Correct pattern: printf(esc_html__('Text (%s)', 'domain'), value)
- Wrong pattern: printf(__('Text (%s)', 'domain'), value) - missing text domain
- Explains why text domain must be in translation function
- Shows proper output escaping with esc_html
2. Twig Translation Filters and HTML Entity Encoding
- Explains why translation filters encode special characters in concatenated strings
- Correct pattern: {{ 'text ' ~ currency_symbol }} (no translation filter)
- Wrong pattern: {{ ('text ' ~ currency_symbol)|__() }} causes HTML entity encoding
- Rule: Only translate static text, not concatenated dynamic values
3. Defensive Programming for POST Data Processing
- Compares v1.2.8 (branching) vs v1.2.9 (defensive) patterns
- Shows why single decision point is better than multiple branches
- Key principles: initialize early, minimize branching, guaranteed execution
- Pattern: initialize → conditionally populate → unconditionally act
Also corrected v1.2.8 examples that had wrong patterns, noting they were fixed in v1.2.9.
These patterns prevent future bugs and ensure consistent, secure implementation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Updated Current Version to 1.2.9
- Moved v1.2.8 bugs to 'Bugfixes (Completed in v1.2.9)' section
- Added detailed fix descriptions for both bugs:
* Translation fix with esc_html__() and proper text domain
* Placeholder encoding fix by removing translation filter
* Variation save logic refactoring with defensive programming
- Updated roadmap section to v1.2.10+
- Added release package and checksums:
* wc-tier-and-package-prices-1.2.9.zip (441KB, 383 files)
* MD5: 073fbf114a32d99cd8ced683a1efa19c
* SHA256: 00d2568e9acfd7fc05c88b9048a6a281d007b55dec9c4c7a4a55cb515e013e97
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
## Bugfixes
1. **Price Header Not Translated**
- Fixed translation function placement in printf statements
- Changed from printf(__()) to printf(esc_html__())
- Headers now display in administrator's configured language
2. **Placeholder HTML Entity Encoding**
- Currency symbols were showing as HTML entities (e.g., €)
- Removed translation filter from concatenated placeholder strings
- Placeholders are example values that should not be translated
3. **Variation Pricing Still Not Deletable (Regression)**
- Despite v1.2.8 fix, edge cases remained due to conditional branching
- Refactored save logic to be more defensive
- Always initializes arrays, then unconditionally updates or deletes
- Guarantees proper cleanup regardless of POST data structure
## Technical Details
- Updated all 6 table headers: printf(esc_html__('Price (%s)', 'wc-tier-package-prices'), ...)
- Removed |__() filter from Twig placeholder concatenations
- Refactored save_variation_pricing_fields() with simplified logic:
* Initialize arrays at start
* Populate only if valid POST data exists
* Always perform update (if !empty) or delete (if empty)
- Added is_array() check for extra safety
## Changed Files
- includes/class-wc-tpp-product-meta.php
- templates/admin/tier-row.twig
- templates/admin/package-row.twig
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added two new critical sections documenting lessons learned during v1.2.8 development:
1. Currency Symbol Display
- Proper pattern for displaying currency in table headers using printf()
- How to pass currency_symbol to Twig templates
- Correct concatenation in Twig placeholders
- List of affected render methods
2. Post Meta Deletion vs. Empty Arrays
- Explains WordPress distinction between deleted meta and empty arrays
- Shows wrong pattern (saving empty arrays) vs correct pattern (deleting meta)
- Why this matters for database cleanliness and bug prevention
- Affected methods in save_tier_package_fields() and save_variation_pricing_fields()
These patterns prevent future bugs and ensure consistent implementation across the codebase.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Updated Current Version to 1.2.8
- Moved v1.2.7 bugs to 'Bugfixes (Completed in v1.2.8)' section
- Added detailed fix descriptions for both bugs
- Updated roadmap section to v1.2.9+
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed two important bugs reported in v1.2.7:
Bug 1: Currency Symbol Missing in Admin Headers and Placeholders
- Table headers now show "Price (CURRENCY)" instead of just "Price"
- Input placeholders include currency symbol (e.g., "9.99 $")
- Better UX for multi-currency stores
Bug 2: Variation Pricing Data Not Deleted Properly (Critical)
- Empty pricing arrays were being saved instead of deleted
- Fixed save logic to check if arrays are empty after filtering
- Properly deletes post meta when all entries are removed
- Affects simple products, variable parents, and variations
Technical changes:
- Updated all table headers with currency symbol display
- Modified all render methods to pass currency_symbol to templates
- Updated Twig templates to use currency in placeholders
- Fixed save_tier_package_fields() and save_variation_pricing_fields()
- Added !empty() checks before update_post_meta() calls
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated documentation to reflect:
- Current version is now 1.2.7
- v1.2.5 issues (table headers, parent pricing forms) are FIXED in v1.2.6/v1.2.7
- Translation updates completed in v1.2.7
- Added critical section on WooCommerce product type-specific hooks
Key learnings documented:
- woocommerce_product_options_pricing only fires for simple products
- woocommerce_product_options_general_product_data fires for all product types
- Proper hook selection is critical for variable product parent UI
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added translations for variable product parent pricing features:
- "Default Tier & Package Pricing for All Variations"
- "Set default pricing for all variations. Individual variations can override these defaults with their own specific pricing."
- "Configure default tier and package pricing here. All variations will inherit these settings unless they define their own specific pricing."
- "Restrict to Package Quantities (Default)"
- "Default restriction setting for all variations. Only allow quantities defined in packages above."
Updated all available language files:
- wc-tier-package-prices.pot (v1.2.7)
- de_CH, de_CH_informal, de_DE, de_DE_informal (German)
- fr_CH (French, Switzerland)
- it_CH (Italian, Switzerland)
- en_US (English, US)
Compiled all .po files to .mo for production use.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed both critical issues that were not resolved in v1.2.6:
1. Variable Product Forms Still Not Showing (Critical)
- v1.2.6 used wrong hook (woocommerce_product_options_pricing)
- That hook only fires for simple products, not variable products
- Changed to woocommerce_product_options_general_product_data
- This hook fires for all product types after general tab
- Forms now appear correctly for variable product parents
2. Table Headers Still Visible When Empty (Critical)
- CSS :has() pseudo-class wasn't working reliably
- Implemented JavaScript + CSS class approach instead
- Added updateTableHeaders() function that toggles has-rows class
- Headers hide by default, show only when table has rows
- Function called on page load and after all add/remove operations
- Works across all browsers without modern CSS requirements
Changed files:
- includes/class-wc-tpp-product-meta.php - Fixed WooCommerce hook
- assets/css/admin.css - Class-based header visibility
- assets/js/admin.js - Added updateTableHeaders() and parent handlers
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed two critical issues that prevented v1.2.5 features from working:
1. Parent Product Pricing Forms Not Visible (Critical)
- Variable products were missing admin UI for parent pricing configuration
- v1.2.5 implemented backend logic but forgot the admin forms
- Added add_variable_parent_pricing_fields() method
- Modified existing methods to skip variable products (simple only)
- Parent pricing now fully functional with matching UI
2. Table Headers Not Hiding When Empty
- CSS sibling selector ~ doesn't work when thead comes before tbody
- Removed incorrect selector, kept only :has() pseudo-class
- Added !important flag for proper specificity
- Modern browser support (Chrome 105+, Firefox 121+, Safari 15.4+)
Changed files:
- includes/class-wc-tpp-product-meta.php - Added parent pricing forms
- assets/css/admin.css - Fixed header hiding CSS
- wc-tier-and-package-prices.php - Version 1.2.6
- composer.json - Version 1.2.6
- CHANGELOG.md - Detailed release notes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added:
- Parent product default pricing for variable products - set tier/package pricing once on parent, variations inherit unless overridden
- Hide empty table headers in admin until pricing rules are defined
Technical:
- Added parent fallback logic to get_tier_price() and get_package_price() methods
- Created helper methods get_packages_with_fallback() and is_restriction_enabled() in cart class
- Updated all cart methods to support parent product defaults
- Added CSS :has() selectors to hide table headers when tbody is empty
- Fixed cart pricing calls to pass correct product ID for fallback resolution
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added comprehensive CSS specificity documentation from v1.2.4 bugfixes:
- CSS Specificity Issues section documenting table border and help-tip positioning problems
- Detailed troubleshooting guide for WooCommerce CSS overrides
- Solution patterns for table styling and float-based layouts
- General rules and diagnostic steps for CSS issues
Updated:
- Last Updated date to 2025-12-30
- Roadmap section to mark v1.2.4 bugs as completed
- Moved future enhancements to v1.2.5+ section
Key learnings documented:
- WooCommerce core CSS requires !important flags for overrides
- Float-based layouts should be replaced with flexbox for precise control
- Table borders require comprehensive targeting of all structural elements
- border-collapse: collapse is essential for borderless tables
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed:
- Admin table borders still visible despite v1.2.3 fix - added !important flags
- Help icon positioning at right edge instead of next to label - changed to flexbox layout
- Increased checkbox margin from 8px to 12px for better spacing
Technical:
- Added border-collapse: collapse !important to force borderless tables
- Changed label layout from float to inline-flex for proper help-tip positioning
- Added comprehensive border removal with !important on all table elements
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fixed two admin UI bugs:
- Applied borderless table styling to all tier/package tables for consistency
- Fixed checkbox tooltip display and improved checkbox-label spacing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>