You've already forked wc-tier-and-package-prices
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b2efb89d59 | |||
| 0f5779dc56 | |||
| d71f2c01dc | |||
| 82c8008fed | |||
| 4871b7957d | |||
| f7508a3d9c | |||
| 23f81ce58c | |||
| 9e96ff3321 | |||
| cf11cb5bd1 | |||
| f26574aa4b | |||
| 348158050e | |||
| d7a61f29b4 | |||
| 10a1f94a31 | |||
| ae946683b3 | |||
| 71ea40598f | |||
| e5aca708cc | |||
| a73ff4926f | |||
| 78101baf88 | |||
| d99ece71e4 | |||
| e4747130e4 | |||
| e4ecc2c0be | |||
| e2e40538df | |||
| 67e11d3030 | |||
| 2de6a92784 | |||
| 47f2ed771b |
0
.claude/commands/.gitignore
vendored
Normal file
0
.claude/commands/.gitignore
vendored
Normal file
@@ -1,5 +0,0 @@
|
||||
# Finish the current session
|
||||
|
||||
Update the CLAUDE.md according to your needs and what you've learned in this session.
|
||||
|
||||
Create a commit and push this file to branch `dev`
|
||||
@@ -21,7 +21,28 @@
|
||||
"Bash(php -l:*)",
|
||||
"Bash(git push:*)",
|
||||
"Bash(git checkout:*)",
|
||||
"Bash(git rebase:*)"
|
||||
"Bash(git rebase:*)",
|
||||
"Bash(git merge:*)",
|
||||
"Bash(git stash:*)",
|
||||
"Bash(for po in languages/*.po)",
|
||||
"Bash('wc-tier-and-package-prices/*.log' )",
|
||||
"Bash('wc-tier-and-package-prices/.claude/*' )",
|
||||
"Bash('wc-tier-and-package-prices/CLAUDE.md' )",
|
||||
"Bash('wc-tier-and-package-prices/releases/*' )",
|
||||
"Bash('wc-tier-and-package-prices/node_modules/*' )",
|
||||
"Bash('wc-tier-and-package-prices/.DS_Store' )",
|
||||
"Bash('wc-tier-and-package-prices/Thumbs.db' )",
|
||||
"Bash('wc-tier-and-package-prices/.vscode/*' )",
|
||||
"Bash('wc-tier-and-package-prices/.idea/*' )",
|
||||
"Bash('wc-tier-and-package-prices/*.sublime-*' )",
|
||||
"Bash('wc-tier-and-package-prices/notes.*' )",
|
||||
"Bash('wc-tier-and-package-prices/logs/*' )",
|
||||
"Bash('wc-tier-and-package-prices/templates/cache/*' )",
|
||||
"Bash('wc-tier-and-package-prices/composer.lock' )",
|
||||
"Bash('*/wordpress/*')",
|
||||
"Bash(echo:*)",
|
||||
"Skill(fix-session)",
|
||||
"Skill(fix-session:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -32,3 +32,4 @@ notes.*
|
||||
|
||||
# local code
|
||||
wordpress
|
||||
core
|
||||
209
CHANGELOG.md
209
CHANGELOG.md
@@ -5,6 +5,215 @@ All notable changes to WooCommerce Tier and Package Prices will be documented in
|
||||
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.2.9] - 2025-12-30
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Price Header Not Translated**: The "Price (%s)" header in admin tables was not being properly translated because the translation function was placed incorrectly within the printf statement. Changed from `printf(__('Price (%s)', ...), ...)` to `printf(esc_html__('Price (%s)', 'wc-tier-package-prices'), ...)` to ensure proper translation while maintaining the currency placeholder functionality.
|
||||
|
||||
- **Placeholder HTML Entity Encoding Issue**: Currency symbols in price input placeholders were being displayed as HTML entities (e.g., "€" instead of "€") because the concatenated string was being passed through the translation filter which was encoding special characters. Removed the unnecessary translation filter from concatenated placeholder strings since they are example values that should not be translated.
|
||||
|
||||
- **Variation Pricing Still Not Deletable (Regression from v1.2.8)**: Despite the fix in v1.2.8, variation pricing data was still not being properly deleted in all scenarios. The issue was with the conditional logic structure - the code had separate `if/else` branches that could fail in edge cases. Restructured the save logic to be more defensive: initialize arrays at the start, populate only if valid POST data exists, then unconditionally perform either update (if not empty) or delete (if empty). This guarantees proper cleanup regardless of POST data structure.
|
||||
|
||||
### Technical Details
|
||||
|
||||
**Translation Fix**:
|
||||
|
||||
- Changed all 6 instances of `printf(__('Price (%s)', 'wc-tier-package-prices'), ...)`
|
||||
- To: `printf(esc_html__('Price (%s)', 'wc-tier-package-prices'), ...)`
|
||||
- The `__()` function now receives the text domain parameter correctly
|
||||
- Added `esc_html` for proper output escaping
|
||||
|
||||
**Placeholder Encoding Fix**:
|
||||
|
||||
- Changed tier-row.twig placeholder from: `{{ ('e.g., 9.99 ' ~ currency_symbol)|__('wc-tier-package-prices') }}`
|
||||
- To: `{{ 'e.g., 9.99 ' ~ currency_symbol }}`
|
||||
- Changed package-row.twig placeholder from: `{{ ('e.g., 99.99 ' ~ currency_symbol)|__('wc-tier-package-prices') }}`
|
||||
- To: `{{ 'e.g., 99.99 ' ~ currency_symbol }}`
|
||||
- Removed translation filter from concatenated example values to prevent HTML entity encoding
|
||||
|
||||
**Variation Save Logic Refactor**:
|
||||
|
||||
```php
|
||||
// Old pattern (v1.2.8):
|
||||
if (isset($_POST['wc_tpp_tiers'][$loop])) {
|
||||
$tiers = array();
|
||||
// ... populate tiers ...
|
||||
if (!empty($tiers)) {
|
||||
update_post_meta(...);
|
||||
} else {
|
||||
delete_post_meta(...);
|
||||
}
|
||||
} else {
|
||||
delete_post_meta(...);
|
||||
}
|
||||
|
||||
// New pattern (v1.2.9):
|
||||
$tiers = array();
|
||||
if (isset($_POST['wc_tpp_tiers'][$loop]) && is_array($_POST['wc_tpp_tiers'][$loop])) {
|
||||
// ... populate tiers ...
|
||||
}
|
||||
// Always perform update or delete based on final state
|
||||
if (!empty($tiers)) {
|
||||
update_post_meta(...);
|
||||
} else {
|
||||
delete_post_meta(...);
|
||||
}
|
||||
```
|
||||
|
||||
- Eliminated conditional branching that could miss edge cases
|
||||
- Added explicit `is_array()` check for extra safety
|
||||
- Guaranteed that one of update_post_meta() or delete_post_meta() is always called
|
||||
- Applied to both `save_variation_pricing_fields()` for tier and package pricing
|
||||
|
||||
**User Impact**:
|
||||
|
||||
- Price headers now display in the administrator's configured language
|
||||
- Currency symbols display correctly without HTML encoding in placeholders
|
||||
- Variation pricing deletion now works reliably in all scenarios
|
||||
- Database remains clean with no orphaned empty arrays
|
||||
|
||||
### Changed Files
|
||||
|
||||
- `includes/class-wc-tpp-product-meta.php` - Fixed translation function calls in 6 table headers; refactored save_variation_pricing_fields() logic for tiers and packages
|
||||
- `templates/admin/tier-row.twig` - Removed translation filter from placeholder concatenation
|
||||
- `templates/admin/package-row.twig` - Removed translation filter from placeholder concatenation
|
||||
|
||||
## [1.2.8] - 2025-12-30
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Currency Symbol Missing in Admin Headers and Placeholders**: Table headers in the admin pricing configuration now display "Price (CURRENCY)" instead of just "Price", making it immediately clear which currency is being used. Price input placeholders now show currency symbol (e.g., "e.g., 9.99 $" instead of "e.g., 9.99"), providing better UX for administrators configuring pricing in different currencies.
|
||||
|
||||
- **Variation Pricing Data Not Deleted Properly (Critical)**: When administrators deleted all tier or package pricing entries from a variation (or simple/parent product) and saved, the empty pricing data was still stored in the database instead of being deleted. This caused variations to retain deleted pricing rules. The save logic now properly detects when the filtered pricing arrays are empty after removing invalid entries and deletes the post meta instead of saving empty arrays.
|
||||
|
||||
### Technical Details
|
||||
|
||||
**Currency Symbol Enhancement**:
|
||||
- Updated all table headers to use `printf(__('Price (%s)', 'wc-tier-package-prices'), get_woocommerce_currency_symbol())`
|
||||
- Modified `render_tier_row()` and `render_package_row()` methods to pass `currency_symbol` to Twig templates
|
||||
- Updated `render_variation_tier_row()` and `render_variation_package_row()` with same currency symbol parameter
|
||||
- Changed Twig template placeholders from `'e.g., 9.99'` to `('e.g., 9.99 ' ~ currency_symbol)`
|
||||
- Affects all pricing contexts: simple products, variable product parents, and variations
|
||||
|
||||
**Pricing Deletion Fix**:
|
||||
- Modified `save_tier_package_fields()` method (simple/parent products) to check `if (!empty($tiers))` before saving
|
||||
- Modified `save_variation_pricing_fields()` method (variations) with same empty check logic
|
||||
- Changed logic from "save on isset, delete otherwise" to "filter entries, then save if not empty, delete if empty"
|
||||
- Applies to both tier pricing and package pricing for all product types
|
||||
- Root cause was filtering out empty entries but still calling `update_post_meta()` with an empty array
|
||||
|
||||
**User Impact**:
|
||||
- Administrators see currency symbol in all pricing configuration interfaces
|
||||
- Clear indication of which currency prices should be entered in
|
||||
- Deleting all pricing rules now properly removes them from the database
|
||||
- No orphaned pricing data remains after deletion
|
||||
- Works correctly for simple products, variable product parents, and variations
|
||||
|
||||
### Changed Files
|
||||
|
||||
- `includes/class-wc-tpp-product-meta.php` - Added currency symbol to all table headers; updated all render methods to pass currency symbol; fixed empty array deletion logic in both save methods
|
||||
- `templates/admin/tier-row.twig` - Updated placeholder to include currency symbol
|
||||
- `templates/admin/package-row.twig` - Updated placeholder to include currency symbol
|
||||
|
||||
## [1.2.7] - 2025-12-30
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Variable Product Forms Still Not Showing (Critical)**: The v1.2.6 fix used the wrong WooCommerce hook. The `woocommerce_product_options_pricing` hook only fires for simple products, not variable products. Changed to use `woocommerce_product_options_general_product_data` hook which fires for all product types after the general tab, allowing the code to check product type and conditionally display the parent pricing fields.
|
||||
|
||||
- **Table Headers Still Visible When Empty (Critical)**: The CSS `:has()` pseudo-class approach from v1.2.6 wasn't working reliably across all browsers. Implemented a JavaScript-based solution that adds/removes a `has-rows` class on tables based on whether they contain pricing rules. Headers now hide by default and show only when the table has rows, with JavaScript updating the state when rows are added or removed.
|
||||
|
||||
### Technical Details
|
||||
|
||||
**Variable Product Hook Fix**:
|
||||
- Changed from `woocommerce_product_options_pricing` to `woocommerce_product_options_general_product_data`
|
||||
- The general product data hook fires for all product types
|
||||
- Method still checks `$product->is_type('variable')` to only show for variable products
|
||||
- This ensures forms appear in the correct location in the WordPress admin
|
||||
|
||||
**Table Header Visibility Fix**:
|
||||
- Replaced CSS-only `:has()` solution with JavaScript + CSS class approach
|
||||
- CSS now uses `.wc-tpp-tiers-table.has-rows thead` to show headers
|
||||
- Added `updateTableHeaders()` JavaScript function that checks row count and toggles class
|
||||
- Function is called on page load and after any add/remove row operation
|
||||
- Works reliably across all browsers without requiring modern CSS features
|
||||
|
||||
**User Impact**:
|
||||
- Variable product parent pricing forms now actually appear in the WordPress admin
|
||||
- Table headers properly hide when empty and show when populated
|
||||
- No browser compatibility issues - works in all modern browsers
|
||||
|
||||
### Changed Files
|
||||
|
||||
- `includes/class-wc-tpp-product-meta.php` - Changed hook from `woocommerce_product_options_pricing` to `woocommerce_product_options_general_product_data`
|
||||
- `assets/css/admin.css` - Replaced `:has()` pseudo-class with class-based approach
|
||||
- `assets/js/admin.js` - Added `updateTableHeaders()` function and calls after all row operations; added handlers for variable product parent forms
|
||||
|
||||
## [1.2.6] - 2025-12-30
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Parent Product Pricing Forms Not Visible (Critical)**: Variable products were missing the pricing configuration forms on the parent product edit page. The v1.2.5 feature for parent product default pricing was implemented in the backend logic (cart calculations and frontend display) but the admin UI to configure these defaults was not added. Now variable product parents have a dedicated "Default Tier & Package Pricing for All Variations" section in the product edit page where administrators can configure default pricing that applies to all variations unless a specific variation overrides it.
|
||||
|
||||
- **Table Headers Not Hiding When Empty**: The CSS selector for hiding table headers when no pricing rules exist was using an incorrect approach. The sibling selector `~` doesn't work when `<thead>` comes before `<tbody>` in the HTML structure. Removed the sibling selector and kept only the `:has()` pseudo-class approach with `!important` flag for proper specificity.
|
||||
|
||||
### Technical Details
|
||||
|
||||
**Parent Product Forms Fix**:
|
||||
- Added new method `add_variable_parent_pricing_fields()` in `WC_TPP_Product_Meta` class
|
||||
- Hooked to `woocommerce_product_options_pricing` action but only displays for variable products
|
||||
- Modified existing `add_tier_pricing_fields()` and `add_package_pricing_fields()` to skip variable products (they now only show for simple products)
|
||||
- Parent product forms use same field names as simple products (`_wc_tpp_tiers`, `_wc_tpp_packages`, `_wc_tpp_restrict_to_packages`)
|
||||
- Data is saved to parent product post meta using existing `save_tier_package_fields()` method
|
||||
- Backend fallback logic from v1.2.5 now has matching admin UI for configuration
|
||||
|
||||
**CSS Selector Fix**:
|
||||
- Removed incorrect `.wc-tpp-tiers-container:empty ~ thead` selector (sibling selector can't target previous elements)
|
||||
- Kept only `.wc-tpp-tiers-table:has(tbody.wc-tpp-tiers-container:empty) thead` with `!important` flag
|
||||
- `:has()` pseudo-class is supported in modern browsers (Chrome 105+, Firefox 121+, Safari 15.4+)
|
||||
|
||||
**User Impact**:
|
||||
- Administrators can now configure default tier/package pricing on variable product parents (feature was non-functional in v1.2.5)
|
||||
- Table headers properly hide when no pricing rules exist, creating cleaner admin interface
|
||||
- No data migration needed - existing configurations remain intact
|
||||
|
||||
### Changed Files
|
||||
|
||||
- `includes/class-wc-tpp-product-meta.php` - Added `add_variable_parent_pricing_fields()` method; modified `add_tier_pricing_fields()` and `add_package_pricing_fields()` to skip variable products
|
||||
- `assets/css/admin.css` - Fixed table header hiding CSS selector; removed incorrect sibling selector; added `!important` flag
|
||||
|
||||
## [1.2.5] - 2025-12-30
|
||||
|
||||
### Added
|
||||
|
||||
- **Parent Product Default Pricing**: Variable products can now define tier and package pricing at the parent product level that applies as defaults to all variations. Individual variations can override these defaults with their own specific pricing. This makes it much easier to set up pricing for products with many variations - set defaults once on the parent, then only customize the variations that need different pricing.
|
||||
|
||||
- **Hide Empty Table Headers**: Table headers for tier and package pricing in the admin area now automatically hide when no pricing rules are defined. This creates a cleaner interface when starting to configure a product, showing only the helpful empty state message and "Add" button.
|
||||
|
||||
### Technical Details
|
||||
|
||||
**Parent Fallback Implementation**:
|
||||
- Modified `WC_TPP_Frontend::get_tier_price()` and `WC_TPP_Frontend::get_package_price()` to fall back to parent product pricing when variation doesn't have its own pricing
|
||||
- Updated `WC_TPP_Cart` to use helper methods `get_packages_with_fallback()` and `is_restriction_enabled()` for consistent parent fallback behavior
|
||||
- All cart validation, quantity restriction, and display methods now support parent product defaults
|
||||
- Fixed cart pricing calls to pass parent `$product_id` instead of `$effective_id` for proper fallback resolution
|
||||
|
||||
**CSS Enhancement**:
|
||||
- Added `:has()` pseudo-class selectors to hide table headers when tbody is empty
|
||||
- Leverages existing empty state message styling for consistent UX
|
||||
|
||||
**Backward Compatibility**:
|
||||
- 100% backward compatible - existing products continue working as before
|
||||
- No database migrations required
|
||||
- Variations with specific pricing take precedence over parent defaults
|
||||
|
||||
### Changed Files
|
||||
|
||||
- `includes/class-wc-tpp-frontend.php` - Added parent fallback logic to `get_tier_price()` and `get_package_price()` methods
|
||||
- `includes/class-wc-tpp-cart.php` - Added helper methods `get_packages_with_fallback()` and `is_restriction_enabled()`; updated all cart methods to support parent fallback; fixed pricing calls to use correct product ID
|
||||
- `assets/css/admin.css` - Added CSS rules to hide table headers when no pricing rules exist
|
||||
|
||||
## [1.2.4] - 2025-12-30
|
||||
|
||||
### Fixed
|
||||
|
||||
264
CLAUDE.md
264
CLAUDE.md
@@ -1,7 +1,7 @@
|
||||
# WooCommerce Tier and Package Prices - AI Context Document
|
||||
|
||||
**Last Updated:** 2025-12-29
|
||||
**Current Version:** 1.2.4
|
||||
**Last Updated:** 2025-12-30
|
||||
**Current Version:** 1.2.9
|
||||
**Author:** Marco Graetsch
|
||||
**Project Status:** Production-ready WordPress plugin
|
||||
|
||||
@@ -305,6 +305,41 @@ Location: includes/class-wc-tpp-cart.php:233
|
||||
- **Fix:** Changed method signature to accept `WC_Product $product` instead of `$cart_item` array
|
||||
- **Status:** FIXED in v1.1.20
|
||||
|
||||
### CSS Specificity Issues (v1.2.3 → v1.2.4)
|
||||
|
||||
**Problem:** Admin table borders still visible despite `border: none` declarations in v1.2.3
|
||||
|
||||
```txt
|
||||
Issue: WooCommerce's core admin CSS has higher specificity border rules
|
||||
Location: assets/css/admin.css
|
||||
Symptom: Tables still showing borders in product edit screens
|
||||
```
|
||||
|
||||
- **Root Cause:** WooCommerce's default admin CSS uses highly specific selectors that override simple `border: none` declarations
|
||||
- **Failed Approach (v1.2.3):** Adding `border: none` to table elements without `!important`
|
||||
- **Successful Fix (v1.2.4):**
|
||||
- Added `!important` flags to ALL border removal rules
|
||||
- Added `border-collapse: collapse !important` to force borderless styling
|
||||
- Targeted all table structural elements: `table`, `th`, `td`, `thead`, `tbody`, `tr`
|
||||
- **Lesson:** When overriding WooCommerce core CSS, `!important` is often necessary due to high specificity in core styles
|
||||
|
||||
**Problem:** Help icon positioned at right edge instead of next to label text
|
||||
|
||||
```txt
|
||||
Issue: WooCommerce help-tip uses float: right positioning
|
||||
Location: assets/css/admin.css (checkbox/label layout)
|
||||
Symptom: Help icon appearing far from label text at container edge
|
||||
```
|
||||
|
||||
- **Root Cause:** WooCommerce's default `.woocommerce-help-tip` styling uses `float: right`
|
||||
- **Failed Approach (v1.2.3):** Simple margin adjustments without changing positioning model
|
||||
- **Successful Fix (v1.2.4):**
|
||||
- Removed float positioning: `float: none`
|
||||
- Changed to `display: inline-block` with `vertical-align: middle`
|
||||
- Wrapped label and help-tip in flexbox container: `display: inline-flex; align-items: center`
|
||||
- Controlled precise spacing with margins (checkbox: 12px, help-tip: 6px)
|
||||
- **Lesson:** Overriding float-based layouts often requires changing to flexbox for proper control
|
||||
|
||||
## Release Process
|
||||
|
||||
### Version Bumping
|
||||
@@ -320,8 +355,8 @@ Update version in 3 places:
|
||||
**CRITICAL:** The zip command must be run from the **parent directory** of the plugin folder to create proper archive structure.
|
||||
|
||||
```bash
|
||||
# From parent directory (/home/magdev/workspaces/node)
|
||||
cd /home/magdev/workspaces/node
|
||||
# From parent directory (/home/magdev/workspaces/php)
|
||||
cd /home/magdev/workspaces/php
|
||||
|
||||
# Create zip excluding dev files - note the correct path structure
|
||||
zip -r wc-tier-and-package-prices/releases/wc-tier-and-package-prices-X.X.X.zip wc-tier-and-package-prices/ \
|
||||
@@ -506,6 +541,89 @@ When modifying admin input fields in Twig templates, use WooCommerce's standard
|
||||
|
||||
**Location:** `templates/admin/*.twig` for admin UI changes
|
||||
|
||||
#### CSS Specificity and WooCommerce Overrides
|
||||
|
||||
**CRITICAL LESSON from v1.2.4:** WooCommerce's core admin CSS uses high-specificity selectors that require `!important` to override.
|
||||
|
||||
**Problem Symptoms:**
|
||||
|
||||
- CSS rules not applying despite correct selectors
|
||||
- Styles work in simple cases but fail with WooCommerce elements
|
||||
- Browser DevTools shows rule crossed out or overridden
|
||||
|
||||
**Diagnostic Steps:**
|
||||
|
||||
1. Inspect element in browser DevTools
|
||||
2. Check "Computed" tab to see which styles are actually applied
|
||||
3. Look for crossed-out rules in "Styles" tab (indicates override)
|
||||
4. Check selector specificity - WooCommerce often uses complex selectors
|
||||
|
||||
**Solution Patterns:**
|
||||
|
||||
**For Table Styling:**
|
||||
|
||||
```css
|
||||
/* ❌ This will likely be overridden */
|
||||
.wc-tpp-tiers-table {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* ✅ Use !important for core WooCommerce overrides */
|
||||
.wc-tpp-tiers-table,
|
||||
.wc-tpp-tiers-table th,
|
||||
.wc-tpp-tiers-table td,
|
||||
.wc-tpp-tiers-table thead,
|
||||
.wc-tpp-tiers-table tbody,
|
||||
.wc-tpp-tiers-table tr {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
/* ✅ Also use border-collapse to prevent cell borders */
|
||||
.wc-tpp-tiers-table {
|
||||
border-collapse: collapse !important;
|
||||
}
|
||||
```
|
||||
|
||||
**For Float-Based Layouts:**
|
||||
|
||||
```css
|
||||
/* ❌ Float positioning is hard to control precisely */
|
||||
.woocommerce-help-tip {
|
||||
float: right;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
/* ✅ Use flexbox for precise control */
|
||||
label[for="_wc_tpp_restrict_to_packages"] {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.woocommerce-help-tip {
|
||||
float: none;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-left: 6px;
|
||||
margin-right: 0;
|
||||
}
|
||||
```
|
||||
|
||||
**General Rules:**
|
||||
|
||||
1. **Always test in actual WordPress admin** - browser preview may not show WooCommerce's CSS
|
||||
2. **Target all related elements** - tables require styling on `table`, `thead`, `tbody`, `tr`, `th`, `td`
|
||||
3. **Use `!important` sparingly but don't fear it** - sometimes it's the only way to override WooCommerce core
|
||||
4. **Prefer flexbox over floats** - gives better control over alignment and spacing
|
||||
5. **Check across browsers** - table rendering can vary between Chrome/Firefox/Safari
|
||||
|
||||
**When Styles Don't Apply:**
|
||||
|
||||
- First verify selector is correct (DevTools should show rule, even if crossed out)
|
||||
- If selector is correct but crossed out, increase specificity or add `!important`
|
||||
- If selector doesn't appear at all, check file is enqueued and cache is cleared
|
||||
- Use browser's "Inspect" right-click to see exact element structure
|
||||
|
||||
#### Git Workflow Issues
|
||||
|
||||
**Problem:** Cannot rebase due to uncommitted changes
|
||||
@@ -580,7 +698,7 @@ zip -r wc-tier-and-package-prices/releases/wc-tier-and-package-prices-X.X.X.zip
|
||||
|
||||
**Critical Exclusions:**
|
||||
|
||||
- `*/wordpress/*` - MUST be excluded! The project has a symlink to WordPress installation that zip will follow, creating 129MB+ packages instead of ~430KB
|
||||
- `*/wordpress/*` and `*/core/*` - MUST be excluded! The project has a symlink to WordPress installation that zip will follow, creating 129MB+ packages instead of ~430KB
|
||||
- `.git/*` - All git metadata (multiple patterns needed for reliability)
|
||||
- `.claude/*` and `CLAUDE.md` - Development documentation
|
||||
- `releases/*` - Prevents including previous releases in new ones
|
||||
@@ -647,7 +765,35 @@ Roadmap for the upcoming development.
|
||||
|
||||
2. ~~Bug 2 in v1.2.3: Increase the margin between checkbox and label and put the help icon right next to the label, not at the right border~~ ✅ **FIXED in v1.2.4** - Increased checkbox right margin from 8px to 12px. Repositioned help tip icon to display inline right next to the label text using flexbox layout with `display: inline-flex`, removing float positioning that caused it to appear at the right edge.
|
||||
|
||||
##### New Features
|
||||
##### Enhancements (Completed in v1.2.5)
|
||||
|
||||
1. ~~Hide the table-headers in admin area until a tier or respectivly a package price is defined.~~ ✅ **COMPLETED in v1.2.5** - Added CSS `:has()` pseudo-class selectors to automatically hide table headers when tbody is empty. Creates a cleaner interface showing only the helpful empty state message and "Add" button when no pricing rules are configured.
|
||||
|
||||
2. ~~Make it possible to define tier or package prices on variable products in the parent product as a default for that product and all variants of it unless a variant has its own tier or package prices.~~ ✅ **COMPLETED in v1.2.5** - Implemented parent product default pricing with automatic fallback. Variable products can define tier/package pricing once at parent level; variations inherit these defaults unless they have their own specific pricing. Added helper methods in cart class and updated all pricing/restriction checks to support parent fallback.
|
||||
|
||||
##### Bugfixes (Completed in v1.2.6 and v1.2.7)
|
||||
|
||||
1. ~~Table headers in admin are still visible when empty.~~ ✅ **FIXED in v1.2.7** - The CSS `:has()` pseudo-class approach from v1.2.5/v1.2.6 wasn't working reliably across all browsers. Implemented JavaScript-based solution that adds/removes `has-rows` class on tables. Headers now hide by default (CSS) and show only when table has rows (JavaScript toggles class). Function `updateTableHeaders()` is called on page load and after all add/remove row operations.
|
||||
|
||||
2. ~~Parent product pricing forms not visible in admin.~~ ✅ **FIXED in v1.2.6 and v1.2.7** - The backend fallback logic from v1.2.5 was implemented but the admin UI to configure it was missing. Added `add_variable_parent_pricing_fields()` method that displays pricing forms for variable product parents. Fixed hook issue in v1.2.7: changed from `woocommerce_product_options_pricing` (only fires for simple products) to `woocommerce_product_options_general_product_data` (fires for all product types). Variable product parents now have a "Default Tier & Package Pricing for All Variations" section where defaults can be configured.
|
||||
|
||||
##### Translation Updates (Completed in v1.2.7)
|
||||
|
||||
1. ✅ **COMPLETED** - Updated all translation files (.pot, .po, .mo) with new strings from v1.2.6 and v1.2.7 for variable product parent pricing features. All 7 language variants updated with translations for "Default Tier & Package Pricing for All Variations" and related strings.
|
||||
|
||||
##### Bugfixes (Completed in v1.2.8)
|
||||
|
||||
1. ~~Add a Suffix with the current configured default currency to the table-header and form placeholder. Use the common currency notation in placeholder~~ ✅ **FIXED in v1.2.8** - Updated all table headers in admin to display "Price (€)" format using `printf(__('Price (%s)'), get_woocommerce_currency_symbol())`. Modified all template render methods (tier_row, package_row, variation_tier_row, variation_package_row) to pass currency_symbol to Twig templates. Updated admin/tier-row.twig and admin/package-row.twig to concatenate currency symbol in price input placeholders (e.g., "e.g., 9.99 €"). Applied to simple products, variable parent products, and all variations.
|
||||
|
||||
2. ~~Already stored tier and package prices on the children of a variable product are still available after deletion. Looks like the storage mechanism has an error. This occurs only on the child product, not on the parent product.~~ ✅ **FIXED in v1.2.8** - Fixed save logic in both `save_tier_package_fields()` and `save_variation_pricing_fields()` methods. Root cause: Empty arrays were being saved via `update_post_meta()` instead of being deleted. Changed logic from "save on isset, delete otherwise" to "filter entries, then save if not empty, delete if empty". Added `if (!empty($tiers))` and `if (!empty($packages))` checks before calling `update_post_meta()`. Now properly calls `delete_post_meta()` when all pricing entries are removed, preventing empty arrays from persisting in database.
|
||||
|
||||
##### Bugfixes (Completed in v1.2.9)
|
||||
|
||||
1. ~~The Price header in admin tables while configuring tier and package prices is not translated. Also the placeholder on the form elements for prices has the wrong encoding, the special characters on the placeholder are show in html-entity encoding.~~ ✅ **FIXED in v1.2.9** - Fixed translation function placement in printf statements by changing from `printf(__('Price (%s)', ...), ...)` to `printf(esc_html__('Price (%s)', 'wc-tier-package-prices'), ...)`. This ensures the text domain is passed correctly to the translation function while maintaining the currency placeholder functionality. Also removed the translation filter from concatenated placeholder strings in Twig templates (changed from `{{ ('e.g., 9.99 ' ~ currency_symbol)|__('wc-tier-package-prices') }}` to `{{ 'e.g., 9.99 ' ~ currency_symbol }}`) because example values should not be translated and the filter was causing HTML entity encoding of special characters.
|
||||
|
||||
2. ~~The tier and package prices for children of a variable product are still not deletable. After storing the product, the previously deleted rows are back again.~~ ✅ **FIXED in v1.2.9** - Despite the fix in v1.2.8, edge cases remained due to conditional branching structure. Refactored `save_variation_pricing_fields()` with more defensive logic: initialize arrays at the start ($tiers = array()), populate only if valid POST data exists (with added is_array() check), then unconditionally perform either update_post_meta() (if !empty) or delete_post_meta() (if empty). This guarantees proper cleanup regardless of POST data structure and eliminates the if/else branching that could miss edge cases.
|
||||
|
||||
##### Planned Enhancements for v1.2.10+
|
||||
|
||||
1. Create different, selectable templates for tierprices and packages to use in the frontend. Make the new templates selectable globally on the settings-page, not per product.
|
||||
|
||||
@@ -665,6 +811,112 @@ Roadmap for the upcoming development.
|
||||
- Always check filter/action documentation for parameter types
|
||||
- Don't assume cart item arrays everywhere - sometimes it's product objects!
|
||||
|
||||
#### CRITICAL: Product Type-Specific Hooks (Learned in v1.2.6/v1.2.7)
|
||||
|
||||
WooCommerce has different hooks for different product types in the admin product edit page:
|
||||
|
||||
- `woocommerce_product_options_pricing` - **ONLY fires for simple products**, NOT variable products
|
||||
- `woocommerce_product_options_general_product_data` - Fires for ALL product types after the general tab
|
||||
- `woocommerce_variation_options_pricing` - Fires for individual variations within variable products
|
||||
|
||||
**Lesson:** When adding admin UI for variable product parents, use `woocommerce_product_options_general_product_data` and check `$product->is_type('variable')` to conditionally display. Using `woocommerce_product_options_pricing` will cause forms to never appear for variable products (as discovered in v1.2.6 → v1.2.7 fix).
|
||||
|
||||
#### CRITICAL: Currency Symbol Display (Learned in v1.2.8)
|
||||
|
||||
When displaying currency symbols in admin interface table headers and input placeholders:
|
||||
|
||||
**Table Headers:**
|
||||
|
||||
```php
|
||||
// ✅ Correct - Use printf with translation and WooCommerce currency function
|
||||
<th><?php printf(__('Price (%s)', 'wc-tier-package-prices'), get_woocommerce_currency_symbol()); ?></th>
|
||||
|
||||
// ❌ Wrong - Hard-coded or missing currency
|
||||
<th><?php _e('Price', 'wc-tier-package-prices'); ?></th>
|
||||
<th><?php _e('Price (€)', 'wc-tier-package-prices'); ?></th>
|
||||
```
|
||||
|
||||
**Twig Template Placeholders:**
|
||||
|
||||
```twig
|
||||
{# ✅ Correct - Pass currency_symbol from PHP and concatenate in template #}
|
||||
placeholder="{{ ('e.g., 9.99 ' ~ currency_symbol)|__('wc-tier-package-prices') }}"
|
||||
|
||||
{# ❌ Wrong - Hard-coded or missing currency #}
|
||||
placeholder="{{ 'e.g., 9.99'|__('wc-tier-package-prices') }}"
|
||||
placeholder="{{ 'e.g., 9.99 €'|__('wc-tier-package-prices') }}"
|
||||
```
|
||||
|
||||
**Implementation Pattern:**
|
||||
|
||||
1. In PHP render methods, pass currency symbol to Twig: `'currency_symbol' => get_woocommerce_currency_symbol()`
|
||||
2. In Twig templates, concatenate using `~` operator: `'text ' ~ currency_symbol`
|
||||
3. Always use WooCommerce's `get_woocommerce_currency_symbol()` - never hard-code currency symbols
|
||||
|
||||
**Affected Methods:** All template render methods must pass `currency_symbol`:
|
||||
|
||||
- `render_tier_row()`
|
||||
- `render_package_row()`
|
||||
- `render_variation_tier_row()`
|
||||
- `render_variation_package_row()`
|
||||
|
||||
#### CRITICAL: Post Meta Deletion vs. Empty Arrays (Learned in v1.2.8)
|
||||
|
||||
When saving product meta data, WordPress distinguishes between "no data" (deleted meta) and "empty data" (empty array saved as meta):
|
||||
|
||||
**Problem Pattern:**
|
||||
|
||||
```php
|
||||
// ❌ WRONG - Saves empty array when all entries removed
|
||||
if (isset($_POST['_wc_tpp_tiers'])) {
|
||||
$tiers = array();
|
||||
foreach ($_POST['_wc_tpp_tiers'] as $tier) {
|
||||
if (!empty($tier['min_qty']) && !empty($tier['price'])) {
|
||||
$tiers[] = array(...);
|
||||
}
|
||||
}
|
||||
update_post_meta($post_id, '_wc_tpp_tiers', $tiers); // Saves [] if no valid entries
|
||||
} else {
|
||||
delete_post_meta($post_id, '_wc_tpp_tiers');
|
||||
}
|
||||
```
|
||||
|
||||
**Correct Pattern:**
|
||||
|
||||
```php
|
||||
// ✅ CORRECT - Deletes meta when no valid entries exist
|
||||
if (isset($_POST['_wc_tpp_tiers'])) {
|
||||
$tiers = array();
|
||||
foreach ($_POST['_wc_tpp_tiers'] as $tier) {
|
||||
if (!empty($tier['min_qty']) && !empty($tier['price'])) {
|
||||
$tiers[] = array(...);
|
||||
}
|
||||
}
|
||||
// Only save if we have valid entries, otherwise delete
|
||||
if (!empty($tiers)) {
|
||||
update_post_meta($post_id, '_wc_tpp_tiers', $tiers);
|
||||
} else {
|
||||
delete_post_meta($post_id, '_wc_tpp_tiers');
|
||||
}
|
||||
} else {
|
||||
delete_post_meta($post_id, '_wc_tpp_tiers');
|
||||
}
|
||||
```
|
||||
|
||||
**Why This Matters:**
|
||||
|
||||
- Empty arrays `[]` saved via `update_post_meta()` persist in database as serialized empty arrays
|
||||
- Frontend/cart code checking `if ($tiers)` will evaluate `[]` as falsy, but meta still exists in database
|
||||
- Database queries like `get_post_meta()` return `[]` instead of `false`, causing subtle bugs
|
||||
- Properly deleting meta keeps database clean and prevents "ghost" configurations
|
||||
|
||||
**Affected Methods in v1.2.8:**
|
||||
|
||||
- `save_tier_package_fields()` - Simple and variable parent products
|
||||
- `save_variation_pricing_fields()` - Individual variations
|
||||
|
||||
**Rule:** Always check `if (!empty($array))` before calling `update_post_meta()` for array data. If empty, call `delete_post_meta()` instead.
|
||||
|
||||
### When Adding Features
|
||||
|
||||
- Follow the existing pattern: add setting → add UI → add logic → add template
|
||||
|
||||
@@ -111,6 +111,19 @@
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Hide table headers when there are no pricing rules */
|
||||
/* Default: hide headers initially, JavaScript will show them when rows are added */
|
||||
.wc-tpp-tiers-table thead,
|
||||
.wc-tpp-packages-table thead {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Show headers when table has pricing rows */
|
||||
.wc-tpp-tiers-table.has-rows thead,
|
||||
.wc-tpp-packages-table.has-rows thead {
|
||||
display: table-header-group !important;
|
||||
}
|
||||
|
||||
/* Checkbox styling improvements */
|
||||
#_wc_tpp_restrict_to_packages,
|
||||
input[id^="wc_tpp_restrict_to_packages_"] {
|
||||
|
||||
@@ -10,6 +10,28 @@
|
||||
let tierIndex = $('.wc-tpp-tier-pricing .wc-tpp-tier-row').length;
|
||||
let packageIndex = $('.wc-tpp-package-pricing .wc-tpp-package-row').length;
|
||||
|
||||
// Function to update table header visibility
|
||||
function updateTableHeaders() {
|
||||
// Check all tier tables
|
||||
$('.wc-tpp-tiers-table').each(function() {
|
||||
const $table = $(this);
|
||||
const $tbody = $table.find('.wc-tpp-tiers-container');
|
||||
const hasRows = $tbody.find('tr').length > 0;
|
||||
$table.toggleClass('has-rows', hasRows);
|
||||
});
|
||||
|
||||
// Check all package tables
|
||||
$('.wc-tpp-packages-table').each(function() {
|
||||
const $table = $(this);
|
||||
const $tbody = $table.find('.wc-tpp-packages-container');
|
||||
const hasRows = $tbody.find('tr').length > 0;
|
||||
$table.toggleClass('has-rows', hasRows);
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize table headers on page load
|
||||
updateTableHeaders();
|
||||
|
||||
// ========================================
|
||||
// Simple Product Handlers
|
||||
// ========================================
|
||||
@@ -21,6 +43,7 @@
|
||||
const newRow = template.replace(/\{\{INDEX\}\}/g, tierIndex);
|
||||
$('.wc-tpp-tier-pricing .wc-tpp-tiers-container').append(newRow);
|
||||
tierIndex++;
|
||||
updateTableHeaders();
|
||||
});
|
||||
|
||||
// Add package (simple products)
|
||||
@@ -30,6 +53,31 @@
|
||||
const newRow = template.replace(/\{\{INDEX\}\}/g, packageIndex);
|
||||
$('.wc-tpp-package-pricing .wc-tpp-packages-container').append(newRow);
|
||||
packageIndex++;
|
||||
updateTableHeaders();
|
||||
});
|
||||
|
||||
// ========================================
|
||||
// Variable Product Parent Handlers
|
||||
// ========================================
|
||||
|
||||
// Add tier (variable product parent default pricing)
|
||||
$('.wc-tpp-variable-parent-pricing .wc-tpp-add-tier').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
const template = $('#wc-tpp-tier-row-template').html();
|
||||
const newRow = template.replace(/\{\{INDEX\}\}/g, tierIndex);
|
||||
$('.wc-tpp-variable-parent-pricing .wc-tpp-tiers-container').append(newRow);
|
||||
tierIndex++;
|
||||
updateTableHeaders();
|
||||
});
|
||||
|
||||
// Add package (variable product parent default pricing)
|
||||
$('.wc-tpp-variable-parent-pricing .wc-tpp-add-package').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
const template = $('#wc-tpp-package-row-template').html();
|
||||
const newRow = template.replace(/\{\{INDEX\}\}/g, packageIndex);
|
||||
$('.wc-tpp-variable-parent-pricing .wc-tpp-packages-container').append(newRow);
|
||||
packageIndex++;
|
||||
updateTableHeaders();
|
||||
});
|
||||
|
||||
// ========================================
|
||||
@@ -50,6 +98,7 @@
|
||||
const newRow = template.replace(/\{\{INDEX\}\}/g, currentIndex);
|
||||
|
||||
$tbody.append(newRow);
|
||||
updateTableHeaders();
|
||||
});
|
||||
|
||||
// Add package (variations)
|
||||
@@ -66,6 +115,7 @@
|
||||
const newRow = template.replace(/\{\{INDEX\}\}/g, currentIndex);
|
||||
|
||||
$tbody.append(newRow);
|
||||
updateTableHeaders();
|
||||
});
|
||||
|
||||
// ========================================
|
||||
@@ -77,6 +127,7 @@
|
||||
e.preventDefault();
|
||||
if (confirm('Are you sure you want to remove this tier?')) {
|
||||
$(this).closest('.wc-tpp-tier-row').remove();
|
||||
updateTableHeaders();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -85,6 +136,7 @@
|
||||
e.preventDefault();
|
||||
if (confirm('Are you sure you want to remove this package?')) {
|
||||
$(this).closest('.wc-tpp-package-row').remove();
|
||||
updateTableHeaders();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "magdev/wc-tier-package-prices",
|
||||
"description": "WooCommerce plugin for tier pricing and package prices with Twig templates",
|
||||
"version": "1.2.4",
|
||||
"version": "1.2.9",
|
||||
"type": "wordpress-plugin",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"authors": [
|
||||
|
||||
@@ -50,10 +50,10 @@ if (!class_exists('WC_TPP_Cart')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for exact package match first (use effective ID for variations)
|
||||
// Check for exact package match first (pass product_id for parent fallback support)
|
||||
$package_price = null;
|
||||
if (get_option('wc_tpp_enable_package_pricing') === 'yes') {
|
||||
$package_price = WC_TPP_Frontend::get_package_price($effective_id, $quantity, $variation_id);
|
||||
$package_price = WC_TPP_Frontend::get_package_price($product_id, $quantity, $variation_id);
|
||||
}
|
||||
|
||||
if ($package_price !== null) {
|
||||
@@ -64,9 +64,9 @@ if (!class_exists('WC_TPP_Cart')) {
|
||||
WC()->cart->cart_contents[$cart_item_key]['wc_tpp_pricing_type'] = 'package';
|
||||
WC()->cart->cart_contents[$cart_item_key]['wc_tpp_total_price'] = $package_price;
|
||||
} else {
|
||||
// Apply tier pricing if no package match (use effective ID for variations)
|
||||
// Apply tier pricing if no package match (pass product_id for parent fallback support)
|
||||
if (get_option('wc_tpp_enable_tier_pricing') === 'yes') {
|
||||
$tier_price = WC_TPP_Frontend::get_tier_price($effective_id, $quantity, $variation_id);
|
||||
$tier_price = WC_TPP_Frontend::get_tier_price($product_id, $quantity, $variation_id);
|
||||
if ($tier_price !== null) {
|
||||
$product->set_price($tier_price);
|
||||
// Store pricing information in cart item for display
|
||||
@@ -103,20 +103,16 @@ if (!class_exists('WC_TPP_Cart')) {
|
||||
public function validate_package_quantity($passed, $product_id, $quantity) {
|
||||
// Check for variation ID in request (for variable products)
|
||||
$variation_id = isset($_REQUEST['variation_id']) ? absint($_REQUEST['variation_id']) : 0;
|
||||
$effective_id = $variation_id > 0 ? $variation_id : $product_id;
|
||||
|
||||
// Check if restriction is enabled globally or for this product/variation
|
||||
$global_restrict = get_option('wc_tpp_restrict_package_quantities', 'no') === 'yes';
|
||||
$product_restrict = get_post_meta($effective_id, '_wc_tpp_restrict_to_packages', true) === 'yes';
|
||||
|
||||
if (!$global_restrict && !$product_restrict) {
|
||||
// Check if restriction is enabled (with parent fallback for variations)
|
||||
if (!$this->is_restriction_enabled($product_id, $variation_id)) {
|
||||
return $passed;
|
||||
}
|
||||
|
||||
// Get packages for this product/variation
|
||||
$packages = get_post_meta($effective_id, '_wc_tpp_packages', true);
|
||||
// Get packages for this product/variation (with parent fallback)
|
||||
$packages = $this->get_packages_with_fallback($product_id, $variation_id);
|
||||
|
||||
if (empty($packages) || !is_array($packages)) {
|
||||
if (!$packages) {
|
||||
return $passed;
|
||||
}
|
||||
|
||||
@@ -156,15 +152,8 @@ if (!class_exists('WC_TPP_Cart')) {
|
||||
$variation_id = isset($cart_item['variation_id']) ? absint($cart_item['variation_id']) : 0;
|
||||
$effective_id = $variation_id > 0 ? $variation_id : $product_id;
|
||||
|
||||
// Check if restriction is enabled globally or for this product/variation
|
||||
$global_restrict = get_option('wc_tpp_restrict_package_quantities', 'no') === 'yes';
|
||||
$product_restrict = get_post_meta($effective_id, '_wc_tpp_restrict_to_packages', true) === 'yes';
|
||||
|
||||
// Get packages for this product/variation
|
||||
$packages = get_post_meta($effective_id, '_wc_tpp_packages', true);
|
||||
|
||||
// If restriction is enabled and packages exist, show quantity as text only
|
||||
if (($global_restrict || $product_restrict) && !empty($packages)) {
|
||||
// Check if restriction is enabled (with parent fallback) and packages exist
|
||||
if ($this->is_restriction_enabled($product_id, $variation_id) && $this->get_packages_with_fallback($product_id, $variation_id)) {
|
||||
return sprintf('<span class="wc-tpp-cart-quantity wc-tpp-restricted-qty" data-product-id="%d">%s</span>',
|
||||
$effective_id,
|
||||
$cart_item['quantity']
|
||||
@@ -179,15 +168,8 @@ if (!class_exists('WC_TPP_Cart')) {
|
||||
$variation_id = isset($cart_item['variation_id']) ? absint($cart_item['variation_id']) : 0;
|
||||
$effective_id = $variation_id > 0 ? $variation_id : $product_id;
|
||||
|
||||
// Check if restriction is enabled globally or for this product/variation
|
||||
$global_restrict = get_option('wc_tpp_restrict_package_quantities', 'no') === 'yes';
|
||||
$product_restrict = get_post_meta($effective_id, '_wc_tpp_restrict_to_packages', true) === 'yes';
|
||||
|
||||
// Get packages for this product/variation
|
||||
$packages = get_post_meta($effective_id, '_wc_tpp_packages', true);
|
||||
|
||||
// If restriction is enabled and packages exist, show quantity as text only
|
||||
if (($global_restrict || $product_restrict) && !empty($packages)) {
|
||||
// Check if restriction is enabled (with parent fallback) and packages exist
|
||||
if ($this->is_restriction_enabled($product_id, $variation_id) && $this->get_packages_with_fallback($product_id, $variation_id)) {
|
||||
return sprintf('<span class="wc-tpp-cart-quantity wc-tpp-restricted-qty" data-product-id="%d">%s ×</span>',
|
||||
$effective_id,
|
||||
$cart_item['quantity']
|
||||
@@ -209,11 +191,8 @@ if (!class_exists('WC_TPP_Cart')) {
|
||||
$variation_id = isset($cart_item['variation_id']) ? absint($cart_item['variation_id']) : 0;
|
||||
$effective_id = $variation_id > 0 ? $variation_id : $product_id;
|
||||
|
||||
$global_restrict = get_option('wc_tpp_restrict_package_quantities', 'no') === 'yes';
|
||||
$product_restrict = get_post_meta($effective_id, '_wc_tpp_restrict_to_packages', true) === 'yes';
|
||||
$packages = get_post_meta($effective_id, '_wc_tpp_packages', true);
|
||||
|
||||
if (($global_restrict || $product_restrict) && !empty($packages)) {
|
||||
// Check if restriction is enabled (with parent fallback) and packages exist
|
||||
if ($this->is_restriction_enabled($product_id, $variation_id) && $this->get_packages_with_fallback($product_id, $variation_id)) {
|
||||
$restricted_products[] = $effective_id;
|
||||
}
|
||||
}
|
||||
@@ -254,20 +233,61 @@ if (!class_exists('WC_TPP_Cart')) {
|
||||
return $editable;
|
||||
}
|
||||
|
||||
// For variations, use the variation ID directly (get_id() returns variation ID for WC_Product_Variation)
|
||||
$effective_id = $product_id;
|
||||
// For variations, get parent product ID and variation ID
|
||||
$variation_id = 0;
|
||||
$parent_id = $product_id;
|
||||
|
||||
$global_restrict = get_option('wc_tpp_restrict_package_quantities', 'no') === 'yes';
|
||||
$product_restrict = get_post_meta($effective_id, '_wc_tpp_restrict_to_packages', true) === 'yes';
|
||||
$packages = get_post_meta($effective_id, '_wc_tpp_packages', true);
|
||||
if ($product->is_type('variation')) {
|
||||
$variation_id = $product_id;
|
||||
$parent_id = $product->get_parent_id();
|
||||
}
|
||||
|
||||
// If restriction is enabled and packages exist, make quantity non-editable
|
||||
if (($global_restrict || $product_restrict) && !empty($packages)) {
|
||||
// Check if restriction is enabled (with parent fallback) and packages exist
|
||||
if ($this->is_restriction_enabled($parent_id, $variation_id) && $this->get_packages_with_fallback($parent_id, $variation_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $editable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get packages with parent fallback for variations
|
||||
*
|
||||
* @param int $product_id Parent product ID
|
||||
* @param int $variation_id Variation ID (0 for simple products)
|
||||
* @return array|false Packages array or false if none found
|
||||
*/
|
||||
private function get_packages_with_fallback($product_id, $variation_id = 0) {
|
||||
$effective_id = $variation_id > 0 ? $variation_id : $product_id;
|
||||
$packages = get_post_meta($effective_id, '_wc_tpp_packages', true);
|
||||
|
||||
// Fall back to parent pricing if variation doesn't have its own pricing
|
||||
if ((empty($packages) || !is_array($packages)) && $variation_id > 0) {
|
||||
$packages = get_post_meta($product_id, '_wc_tpp_packages', true);
|
||||
}
|
||||
|
||||
return (!empty($packages) && is_array($packages)) ? $packages : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if restriction is enabled for a product/variation with parent fallback
|
||||
*
|
||||
* @param int $product_id Parent product ID
|
||||
* @param int $variation_id Variation ID (0 for simple products)
|
||||
* @return bool Whether restriction is enabled
|
||||
*/
|
||||
private function is_restriction_enabled($product_id, $variation_id = 0) {
|
||||
$effective_id = $variation_id > 0 ? $variation_id : $product_id;
|
||||
$global_restrict = get_option('wc_tpp_restrict_package_quantities', 'no') === 'yes';
|
||||
$product_restrict = get_post_meta($effective_id, '_wc_tpp_restrict_to_packages', true) === 'yes';
|
||||
|
||||
// Fall back to parent restriction setting if variation doesn't have its own
|
||||
if (!$product_restrict && $variation_id > 0) {
|
||||
$product_restrict = get_post_meta($product_id, '_wc_tpp_restrict_to_packages', true) === 'yes';
|
||||
}
|
||||
|
||||
return $global_restrict || $product_restrict;
|
||||
}
|
||||
}
|
||||
|
||||
new WC_TPP_Cart();
|
||||
|
||||
@@ -133,6 +133,11 @@ if (!class_exists('WC_TPP_Frontend')) {
|
||||
$effective_id = $variation_id > 0 ? $variation_id : $product_id;
|
||||
$tiers = get_post_meta($effective_id, '_wc_tpp_tiers', true);
|
||||
|
||||
// Fall back to parent pricing if variation doesn't have its own pricing
|
||||
if ((empty($tiers) || !is_array($tiers)) && $variation_id > 0) {
|
||||
$tiers = get_post_meta($product_id, '_wc_tpp_tiers', true);
|
||||
}
|
||||
|
||||
if (empty($tiers) || !is_array($tiers)) {
|
||||
return null;
|
||||
}
|
||||
@@ -159,6 +164,11 @@ if (!class_exists('WC_TPP_Frontend')) {
|
||||
$effective_id = $variation_id > 0 ? $variation_id : $product_id;
|
||||
$packages = get_post_meta($effective_id, '_wc_tpp_packages', true);
|
||||
|
||||
// Fall back to parent pricing if variation doesn't have its own pricing
|
||||
if ((empty($packages) || !is_array($packages)) && $variation_id > 0) {
|
||||
$packages = get_post_meta($product_id, '_wc_tpp_packages', true);
|
||||
}
|
||||
|
||||
if (empty($packages) || !is_array($packages)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -16,13 +16,128 @@ if (!class_exists('WC_TPP_Product_Meta')) {
|
||||
add_action('woocommerce_product_options_pricing', array($this, 'add_package_pricing_fields'));
|
||||
add_action('woocommerce_process_product_meta', array($this, 'save_tier_package_fields'));
|
||||
|
||||
// Variable product parent hooks (for default pricing)
|
||||
// Use product_options_general_product_data which shows for all product types after the general tab
|
||||
add_action('woocommerce_product_options_general_product_data', array($this, 'add_variable_parent_pricing_fields'));
|
||||
|
||||
// Variable product variation hooks
|
||||
add_action('woocommerce_variation_options_pricing', array($this, 'add_variation_pricing_fields'), 10, 3);
|
||||
add_action('woocommerce_save_product_variation', array($this, 'save_variation_pricing_fields'), 10, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add tier and package pricing fields for variable product parents
|
||||
* These serve as defaults for all variations unless overridden
|
||||
*/
|
||||
public function add_variable_parent_pricing_fields() {
|
||||
global $post;
|
||||
|
||||
// Only show for variable products, not simple products
|
||||
$product = wc_get_product($post->ID);
|
||||
if (!$product || !$product->is_type('variable')) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="options_group wc-tpp-variable-parent-pricing">
|
||||
<p class="form-field">
|
||||
<strong><?php _e('Default Tier & Package Pricing for All Variations', 'wc-tier-package-prices'); ?></strong>
|
||||
<span class="woocommerce-help-tip" data-tip="<?php esc_attr_e('Set default pricing for all variations. Individual variations can override these defaults with their own specific pricing.', 'wc-tier-package-prices'); ?>"></span>
|
||||
</p>
|
||||
<p class="description" style="margin-left: 12px; margin-bottom: 15px;">
|
||||
<?php _e('Configure default tier and package pricing here. All variations will inherit these settings unless they define their own specific pricing.', 'wc-tier-package-prices'); ?>
|
||||
</p>
|
||||
|
||||
<!-- Tier Pricing Section -->
|
||||
<div class="wc-tpp-parent-tier-pricing" style="margin-left: 12px;">
|
||||
<p><strong><?php _e('Tier Pricing', 'wc-tier-package-prices'); ?></strong></p>
|
||||
<table class="widefat wc-tpp-tiers-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('Min Quantity', 'wc-tier-package-prices'); ?></th>
|
||||
<th><?php printf(esc_html__('Price (%s)', 'wc-tier-package-prices'), get_woocommerce_currency_symbol()); ?></th>
|
||||
<th><?php _e('Label (optional)', 'wc-tier-package-prices'); ?></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="wc-tpp-tiers-container">
|
||||
<?php
|
||||
$tiers = get_post_meta($post->ID, '_wc_tpp_tiers', true);
|
||||
if (!is_array($tiers)) {
|
||||
$tiers = array();
|
||||
}
|
||||
|
||||
foreach ($tiers as $index => $tier) {
|
||||
$this->render_tier_row($index, $tier);
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="form-field">
|
||||
<button type="button" class="button wc-tpp-add-tier"><?php _e('Add Tier', 'wc-tier-package-prices'); ?></button>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Package Pricing Section -->
|
||||
<div class="wc-tpp-parent-package-pricing" style="margin-left: 12px; margin-top: 20px;">
|
||||
<p><strong><?php _e('Package Pricing', 'wc-tier-package-prices'); ?></strong></p>
|
||||
<table class="widefat wc-tpp-packages-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('Quantity', 'wc-tier-package-prices'); ?></th>
|
||||
<th><?php printf(esc_html__('Price (%s)', 'wc-tier-package-prices'), get_woocommerce_currency_symbol()); ?></th>
|
||||
<th><?php _e('Label (optional)', 'wc-tier-package-prices'); ?></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="wc-tpp-packages-container">
|
||||
<?php
|
||||
$packages = get_post_meta($post->ID, '_wc_tpp_packages', true);
|
||||
if (!is_array($packages)) {
|
||||
$packages = array();
|
||||
}
|
||||
|
||||
foreach ($packages as $index => $package) {
|
||||
$this->render_package_row($index, $package);
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="form-field">
|
||||
<button type="button" class="button wc-tpp-add-package"><?php _e('Add Package', 'wc-tier-package-prices'); ?></button>
|
||||
</p>
|
||||
|
||||
<?php
|
||||
woocommerce_wp_checkbox(array(
|
||||
'id' => '_wc_tpp_restrict_to_packages',
|
||||
'label' => __('Restrict to Package Quantities (Default)', 'wc-tier-package-prices'),
|
||||
'description' => __('Default restriction setting for all variations. Only allow quantities defined in packages above.', 'wc-tier-package-prices'),
|
||||
'desc_tip' => true,
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
|
||||
<!-- Templates for JavaScript (shared between simple and variable parent) -->
|
||||
<script type="text/html" id="wc-tpp-tier-row-template">
|
||||
<?php $this->render_tier_row('{{INDEX}}', array('min_qty' => '', 'price' => '', 'label' => '')); ?>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="wc-tpp-package-row-template">
|
||||
<?php $this->render_package_row('{{INDEX}}', array('qty' => '', 'price' => '', 'label' => '')); ?>
|
||||
</script>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function add_tier_pricing_fields() {
|
||||
global $post;
|
||||
|
||||
// Only show for simple products (variable products use add_variable_parent_pricing_fields)
|
||||
$product = wc_get_product($post->ID);
|
||||
if ($product && $product->is_type('variable')) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="options_group wc-tpp-tier-pricing">
|
||||
<p class="form-field">
|
||||
@@ -34,7 +149,7 @@ if (!class_exists('WC_TPP_Product_Meta')) {
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('Min Quantity', 'wc-tier-package-prices'); ?></th>
|
||||
<th><?php _e('Price', 'wc-tier-package-prices'); ?></th>
|
||||
<th><?php printf(esc_html__('Price (%s)', 'wc-tier-package-prices'), get_woocommerce_currency_symbol()); ?></th>
|
||||
<th><?php _e('Label (optional)', 'wc-tier-package-prices'); ?></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
@@ -62,6 +177,13 @@ if (!class_exists('WC_TPP_Product_Meta')) {
|
||||
|
||||
public function add_package_pricing_fields() {
|
||||
global $post;
|
||||
|
||||
// Only show for simple products (variable products use add_variable_parent_pricing_fields)
|
||||
$product = wc_get_product($post->ID);
|
||||
if ($product && $product->is_type('variable')) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="options_group wc-tpp-package-pricing">
|
||||
<p class="form-field">
|
||||
@@ -73,7 +195,7 @@ if (!class_exists('WC_TPP_Product_Meta')) {
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('Quantity', 'wc-tier-package-prices'); ?></th>
|
||||
<th><?php _e('Price', 'wc-tier-package-prices'); ?></th>
|
||||
<th><?php printf(esc_html__('Price (%s)', 'wc-tier-package-prices'), get_woocommerce_currency_symbol()); ?></th>
|
||||
<th><?php _e('Label (optional)', 'wc-tier-package-prices'); ?></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
@@ -119,14 +241,16 @@ if (!class_exists('WC_TPP_Product_Meta')) {
|
||||
private function render_tier_row($index, $tier) {
|
||||
WC_TPP_Template_Loader::get_instance()->display('admin/tier-row.twig', array(
|
||||
'index' => $index,
|
||||
'tier' => $tier
|
||||
'tier' => $tier,
|
||||
'currency_symbol' => get_woocommerce_currency_symbol()
|
||||
));
|
||||
}
|
||||
|
||||
private function render_package_row($index, $package) {
|
||||
WC_TPP_Template_Loader::get_instance()->display('admin/package-row.twig', array(
|
||||
'index' => $index,
|
||||
'package' => $package
|
||||
'package' => $package,
|
||||
'currency_symbol' => get_woocommerce_currency_symbol()
|
||||
));
|
||||
}
|
||||
|
||||
@@ -163,7 +287,7 @@ if (!class_exists('WC_TPP_Product_Meta')) {
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('Min Quantity', 'wc-tier-package-prices'); ?></th>
|
||||
<th><?php _e('Price', 'wc-tier-package-prices'); ?></th>
|
||||
<th><?php printf(esc_html__('Price (%s)', 'wc-tier-package-prices'), get_woocommerce_currency_symbol()); ?></th>
|
||||
<th><?php _e('Label (optional)', 'wc-tier-package-prices'); ?></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
@@ -186,7 +310,7 @@ if (!class_exists('WC_TPP_Product_Meta')) {
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php _e('Quantity', 'wc-tier-package-prices'); ?></th>
|
||||
<th><?php _e('Price', 'wc-tier-package-prices'); ?></th>
|
||||
<th><?php printf(esc_html__('Price (%s)', 'wc-tier-package-prices'), get_woocommerce_currency_symbol()); ?></th>
|
||||
<th><?php _e('Label (optional)', 'wc-tier-package-prices'); ?></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
@@ -241,7 +365,8 @@ if (!class_exists('WC_TPP_Product_Meta')) {
|
||||
WC_TPP_Template_Loader::get_instance()->display('admin/tier-row.twig', array(
|
||||
'index' => $index,
|
||||
'tier' => $tier,
|
||||
'field_prefix' => 'wc_tpp_tiers[' . $loop . ']'
|
||||
'field_prefix' => 'wc_tpp_tiers[' . $loop . ']',
|
||||
'currency_symbol' => get_woocommerce_currency_symbol()
|
||||
));
|
||||
}
|
||||
|
||||
@@ -256,7 +381,8 @@ if (!class_exists('WC_TPP_Product_Meta')) {
|
||||
WC_TPP_Template_Loader::get_instance()->display('admin/package-row.twig', array(
|
||||
'index' => $index,
|
||||
'package' => $package,
|
||||
'field_prefix' => 'wc_tpp_packages[' . $loop . ']'
|
||||
'field_prefix' => 'wc_tpp_packages[' . $loop . ']',
|
||||
'currency_symbol' => get_woocommerce_currency_symbol()
|
||||
));
|
||||
}
|
||||
|
||||
@@ -292,10 +418,15 @@ if (!class_exists('WC_TPP_Product_Meta')) {
|
||||
usort($tiers, function($a, $b) {
|
||||
return $a['min_qty'] - $b['min_qty'];
|
||||
});
|
||||
// Only save if we have valid tiers, otherwise delete
|
||||
if (!empty($tiers)) {
|
||||
update_post_meta($post_id, '_wc_tpp_tiers', $tiers);
|
||||
} else {
|
||||
delete_post_meta($post_id, '_wc_tpp_tiers');
|
||||
}
|
||||
} else {
|
||||
delete_post_meta($post_id, '_wc_tpp_tiers');
|
||||
}
|
||||
|
||||
// Save package pricing
|
||||
if (isset($_POST['_wc_tpp_packages'])) {
|
||||
@@ -313,10 +444,15 @@ if (!class_exists('WC_TPP_Product_Meta')) {
|
||||
usort($packages, function($a, $b) {
|
||||
return $a['qty'] - $b['qty'];
|
||||
});
|
||||
// Only save if we have valid packages, otherwise delete
|
||||
if (!empty($packages)) {
|
||||
update_post_meta($post_id, '_wc_tpp_packages', $packages);
|
||||
} else {
|
||||
delete_post_meta($post_id, '_wc_tpp_packages');
|
||||
}
|
||||
} else {
|
||||
delete_post_meta($post_id, '_wc_tpp_packages');
|
||||
}
|
||||
|
||||
// Save package quantity restriction setting
|
||||
$restrict_to_packages = isset($_POST['_wc_tpp_restrict_to_packages']) ? 'yes' : 'no';
|
||||
@@ -336,8 +472,8 @@ if (!class_exists('WC_TPP_Product_Meta')) {
|
||||
}
|
||||
|
||||
// Save tier pricing for this variation
|
||||
if (isset($_POST['wc_tpp_tiers'][$loop])) {
|
||||
$tiers = array();
|
||||
if (isset($_POST['wc_tpp_tiers'][$loop]) && is_array($_POST['wc_tpp_tiers'][$loop])) {
|
||||
foreach ($_POST['wc_tpp_tiers'][$loop] as $tier) {
|
||||
if (!empty($tier['min_qty']) && !empty($tier['price'])) {
|
||||
$tiers[] = array(
|
||||
@@ -351,14 +487,17 @@ if (!class_exists('WC_TPP_Product_Meta')) {
|
||||
usort($tiers, function($a, $b) {
|
||||
return $a['min_qty'] - $b['min_qty'];
|
||||
});
|
||||
}
|
||||
// Always update or delete based on whether we have valid tiers
|
||||
if (!empty($tiers)) {
|
||||
update_post_meta($variation_id, '_wc_tpp_tiers', $tiers);
|
||||
} else {
|
||||
delete_post_meta($variation_id, '_wc_tpp_tiers');
|
||||
}
|
||||
|
||||
// Save package pricing for this variation
|
||||
if (isset($_POST['wc_tpp_packages'][$loop])) {
|
||||
$packages = array();
|
||||
if (isset($_POST['wc_tpp_packages'][$loop]) && is_array($_POST['wc_tpp_packages'][$loop])) {
|
||||
foreach ($_POST['wc_tpp_packages'][$loop] as $package) {
|
||||
if (!empty($package['qty']) && !empty($package['price'])) {
|
||||
$packages[] = array(
|
||||
@@ -372,6 +511,9 @@ if (!class_exists('WC_TPP_Product_Meta')) {
|
||||
usort($packages, function($a, $b) {
|
||||
return $a['qty'] - $b['qty'];
|
||||
});
|
||||
}
|
||||
// Always update or delete based on whether we have valid packages
|
||||
if (!empty($packages)) {
|
||||
update_post_meta($variation_id, '_wc_tpp_packages', $packages);
|
||||
} else {
|
||||
delete_post_meta($variation_id, '_wc_tpp_packages');
|
||||
|
||||
Binary file not shown.
@@ -3,10 +3,10 @@
|
||||
# This file is distributed under the GPL v2 or later.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: WooCommerce Tier and Package Prices 1.1.21\n"
|
||||
"Project-Id-Version: WooCommerce Tier and Package Prices 1.2.7\n"
|
||||
"Report-Msgid-Bugs-To: https://src.bundespruefstelle.ch/wc-tier-package-prices\n"
|
||||
"POT-Creation-Date: 2025-12-23 00:00+0000\n"
|
||||
"PO-Revision-Date: 2025-12-23 00:00+0000\n"
|
||||
"POT-Creation-Date: 2025-12-30 00:00+0000\n"
|
||||
"PO-Revision-Date: 2025-12-30 00:00+0000\n"
|
||||
"Last-Translator: Marco Graetsch\n"
|
||||
"Language-Team: German (Switzerland)\n"
|
||||
"Language: de_CH\n"
|
||||
@@ -152,6 +152,26 @@ msgstr "Paket hinzufügen"
|
||||
msgid "Only allow quantities defined in packages above"
|
||||
msgstr "Nur oben definierte Paketmengen zulassen"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:42
|
||||
msgid "Default Tier & Package Pricing for All Variations"
|
||||
msgstr "Standard Staffel- & Paketpreise für alle Varianten"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:43
|
||||
msgid "Set default pricing for all variations. Individual variations can override these defaults with their own specific pricing."
|
||||
msgstr "Legen Sie Standardpreise für alle Varianten fest. Einzelne Varianten können diese Standardwerte mit ihren eigenen spezifischen Preisen überschreiben."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:44
|
||||
msgid "Configure default tier and package pricing here. All variations will inherit these settings unless they define their own specific pricing."
|
||||
msgstr "Konfigurieren Sie hier Standard-Staffel- und Paketpreise. Alle Varianten übernehmen diese Einstellungen, es sei denn, sie definieren ihre eigenen spezifischen Preise."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:87
|
||||
msgid "Restrict to Package Quantities (Default)"
|
||||
msgstr "Auf Paketmengen beschränken (Standard)"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:88
|
||||
msgid "Default restriction setting for all variations. Only allow quantities defined in packages above."
|
||||
msgstr "Standard-Beschränkungseinstellung für alle Varianten. Nur oben definierte Paketmengen zulassen."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:90
|
||||
msgid "Minimum Quantity"
|
||||
msgstr "Mindestmenge"
|
||||
|
||||
Binary file not shown.
@@ -3,10 +3,10 @@
|
||||
# This file is distributed under the GPL v2 or later.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: WooCommerce Tier and Package Prices 1.1.6\n"
|
||||
"Project-Id-Version: WooCommerce Tier and Package Prices 1.2.7\n"
|
||||
"Report-Msgid-Bugs-To: https://src.bundespruefstelle.ch/wc-tier-package-prices\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:00+0000\n"
|
||||
"PO-Revision-Date: 2025-12-21 00:00+0000\n"
|
||||
"POT-Creation-Date: 2025-12-30 00:00+0000\n"
|
||||
"PO-Revision-Date: 2025-12-30 00:00+0000\n"
|
||||
"Last-Translator: Marco Graetsch\n"
|
||||
"Language-Team: German (Switzerland)\n"
|
||||
"Language: de_CH_informal\n"
|
||||
@@ -152,6 +152,26 @@ msgstr "Paket hinzufügen"
|
||||
msgid "Only allow quantities defined in packages above"
|
||||
msgstr "Nur oben definierte Paketmengen zulassen"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:42
|
||||
msgid "Default Tier & Package Pricing for All Variations"
|
||||
msgstr "Standard Staffel- & Paketpreise für alle Varianten"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:43
|
||||
msgid "Set default pricing for all variations. Individual variations can override these defaults with their own specific pricing."
|
||||
msgstr "Lege Standardpreise für alle Varianten fest. Einzelne Varianten können diese Standardwerte mit ihren eigenen spezifischen Preisen überschreiben."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:44
|
||||
msgid "Configure default tier and package pricing here. All variations will inherit these settings unless they define their own specific pricing."
|
||||
msgstr "Konfiguriere hier Standard-Staffel- und Paketpreise. Alle Varianten übernehmen diese Einstellungen, es sei denn, sie definieren ihre eigenen spezifischen Preise."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:87
|
||||
msgid "Restrict to Package Quantities (Default)"
|
||||
msgstr "Auf Paketmengen beschränken (Standard)"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:88
|
||||
msgid "Default restriction setting for all variations. Only allow quantities defined in packages above."
|
||||
msgstr "Standard-Beschränkungseinstellung für alle Varianten. Nur oben definierte Paketmengen zulassen."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:90
|
||||
msgid "Minimum Quantity"
|
||||
msgstr "Mindestmenge"
|
||||
|
||||
Binary file not shown.
@@ -3,10 +3,10 @@
|
||||
# This file is distributed under the GPL v2 or later.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: WooCommerce Tier and Package Prices 1.1.6\n"
|
||||
"Project-Id-Version: WooCommerce Tier and Package Prices 1.2.7\n"
|
||||
"Report-Msgid-Bugs-To: https://src.bundespruefstelle.ch/wc-tier-package-prices\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:00+0000\n"
|
||||
"PO-Revision-Date: 2025-12-21 00:00+0000\n"
|
||||
"POT-Creation-Date: 2025-12-30 00:00+0000\n"
|
||||
"PO-Revision-Date: 2025-12-30 00:00+0000\n"
|
||||
"Last-Translator: Marco Graetsch\n"
|
||||
"Language-Team: German\n"
|
||||
"Language: de_DE\n"
|
||||
@@ -152,6 +152,26 @@ msgstr "Paket hinzufügen"
|
||||
msgid "Only allow quantities defined in packages above"
|
||||
msgstr "Nur oben definierte Paketmengen zulassen"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:42
|
||||
msgid "Default Tier & Package Pricing for All Variations"
|
||||
msgstr "Standard Staffel- & Paketpreise für alle Varianten"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:43
|
||||
msgid "Set default pricing for all variations. Individual variations can override these defaults with their own specific pricing."
|
||||
msgstr "Legen Sie Standardpreise für alle Varianten fest. Einzelne Varianten können diese Standardwerte mit ihren eigenen spezifischen Preisen überschreiben."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:44
|
||||
msgid "Configure default tier and package pricing here. All variations will inherit these settings unless they define their own specific pricing."
|
||||
msgstr "Konfigurieren Sie hier Standard-Staffel- und Paketpreise. Alle Varianten übernehmen diese Einstellungen, es sei denn, sie definieren ihre eigenen spezifischen Preise."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:87
|
||||
msgid "Restrict to Package Quantities (Default)"
|
||||
msgstr "Auf Paketmengen beschränken (Standard)"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:88
|
||||
msgid "Default restriction setting for all variations. Only allow quantities defined in packages above."
|
||||
msgstr "Standard-Beschränkungseinstellung für alle Varianten. Nur oben definierte Paketmengen zulassen."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:90
|
||||
msgid "Minimum Quantity"
|
||||
msgstr "Mindestmenge"
|
||||
|
||||
Binary file not shown.
@@ -3,10 +3,10 @@
|
||||
# This file is distributed under the GPL v2 or later.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: WooCommerce Tier and Package Prices 1.1.21\n"
|
||||
"Project-Id-Version: WooCommerce Tier and Package Prices 1.2.7\n"
|
||||
"Report-Msgid-Bugs-To: https://src.bundespruefstelle.ch/wc-tier-package-prices\n"
|
||||
"POT-Creation-Date: 2025-12-23 00:00+0000\n"
|
||||
"PO-Revision-Date: 2025-12-23 00:00+0000\n"
|
||||
"POT-Creation-Date: 2025-12-30 00:00+0000\n"
|
||||
"PO-Revision-Date: 2025-12-30 00:00+0000\n"
|
||||
"Last-Translator: Marco Graetsch\n"
|
||||
"Language-Team: German (Germany)\n"
|
||||
"Language: de_DE_informal\n"
|
||||
@@ -152,6 +152,26 @@ msgstr "Paket hinzufügen"
|
||||
msgid "Only allow quantities defined in packages above"
|
||||
msgstr "Nur oben definierte Paketmengen zulassen"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:42
|
||||
msgid "Default Tier & Package Pricing for All Variations"
|
||||
msgstr "Standard Staffel- & Paketpreise für alle Varianten"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:43
|
||||
msgid "Set default pricing for all variations. Individual variations can override these defaults with their own specific pricing."
|
||||
msgstr "Lege Standardpreise für alle Varianten fest. Einzelne Varianten können diese Standardwerte mit ihren eigenen spezifischen Preisen überschreiben."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:44
|
||||
msgid "Configure default tier and package pricing here. All variations will inherit these settings unless they define their own specific pricing."
|
||||
msgstr "Konfiguriere hier Standard-Staffel- und Paketpreise. Alle Varianten übernehmen diese Einstellungen, es sei denn, sie definieren ihre eigenen spezifischen Preise."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:87
|
||||
msgid "Restrict to Package Quantities (Default)"
|
||||
msgstr "Auf Paketmengen beschränken (Standard)"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:88
|
||||
msgid "Default restriction setting for all variations. Only allow quantities defined in packages above."
|
||||
msgstr "Standard-Beschränkungseinstellung für alle Varianten. Nur oben definierte Paketmengen zulassen."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:90
|
||||
msgid "Minimum Quantity"
|
||||
msgstr "Mindestmenge"
|
||||
|
||||
Binary file not shown.
@@ -3,10 +3,10 @@
|
||||
# This file is distributed under the GPL v2 or later.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: WooCommerce Tier and Package Prices 1.1.6\n"
|
||||
"Project-Id-Version: WooCommerce Tier and Package Prices 1.2.7\n"
|
||||
"Report-Msgid-Bugs-To: https://src.bundespruefstelle.ch/wc-tier-package-prices\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:00+0000\n"
|
||||
"PO-Revision-Date: 2025-12-21 00:00+0000\n"
|
||||
"POT-Creation-Date: 2025-12-30 00:00+0000\n"
|
||||
"PO-Revision-Date: 2025-12-30 00:00+0000\n"
|
||||
"Last-Translator: Marco Graetsch\n"
|
||||
"Language-Team: English\n"
|
||||
"Language: en_US\n"
|
||||
@@ -152,6 +152,26 @@ msgstr "Add Package"
|
||||
msgid "Only allow quantities defined in packages above"
|
||||
msgstr "Only allow quantities defined in packages above"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:42
|
||||
msgid "Default Tier & Package Pricing for All Variations"
|
||||
msgstr "Default Tier & Package Pricing for All Variations"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:43
|
||||
msgid "Set default pricing for all variations. Individual variations can override these defaults with their own specific pricing."
|
||||
msgstr "Set default pricing for all variations. Individual variations can override these defaults with their own specific pricing."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:44
|
||||
msgid "Configure default tier and package pricing here. All variations will inherit these settings unless they define their own specific pricing."
|
||||
msgstr "Configure default tier and package pricing here. All variations will inherit these settings unless they define their own specific pricing."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:87
|
||||
msgid "Restrict to Package Quantities (Default)"
|
||||
msgstr "Restrict to Package Quantities (Default)"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:88
|
||||
msgid "Default restriction setting for all variations. Only allow quantities defined in packages above."
|
||||
msgstr "Default restriction setting for all variations. Only allow quantities defined in packages above."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:90
|
||||
msgid "Minimum Quantity"
|
||||
msgstr "Minimum Quantity"
|
||||
|
||||
Binary file not shown.
@@ -3,10 +3,10 @@
|
||||
# This file is distributed under the GPL v2 or later.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: WooCommerce Tier and Package Prices 1.1.21\n"
|
||||
"Project-Id-Version: WooCommerce Tier and Package Prices 1.2.7\n"
|
||||
"Report-Msgid-Bugs-To: https://src.bundespruefstelle.ch/wc-tier-package-prices\n"
|
||||
"POT-Creation-Date: 2025-12-23 00:00+0000\n"
|
||||
"PO-Revision-Date: 2025-12-23 00:00+0000\n"
|
||||
"POT-Creation-Date: 2025-12-30 00:00+0000\n"
|
||||
"PO-Revision-Date: 2025-12-30 00:00+0000\n"
|
||||
"Last-Translator: Marco Graetsch\n"
|
||||
"Language-Team: French (Switzerland)\n"
|
||||
"Language: fr_CH\n"
|
||||
@@ -152,6 +152,26 @@ msgstr "Ajouter un forfait"
|
||||
msgid "Only allow quantities defined in packages above"
|
||||
msgstr "Autoriser uniquement les quantités définies dans les forfaits ci-dessus"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:42
|
||||
msgid "Default Tier & Package Pricing for All Variations"
|
||||
msgstr "Tarification par paliers et forfaits par défaut pour toutes les variations"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:43
|
||||
msgid "Set default pricing for all variations. Individual variations can override these defaults with their own specific pricing."
|
||||
msgstr "Définir la tarification par défaut pour toutes les variations. Les variations individuelles peuvent remplacer ces valeurs par défaut par leur propre tarification spécifique."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:44
|
||||
msgid "Configure default tier and package pricing here. All variations will inherit these settings unless they define their own specific pricing."
|
||||
msgstr "Configurez ici la tarification par paliers et forfaits par défaut. Toutes les variations hériteront de ces paramètres sauf si elles définissent leur propre tarification spécifique."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:87
|
||||
msgid "Restrict to Package Quantities (Default)"
|
||||
msgstr "Limiter aux quantités de forfaits (par défaut)"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:88
|
||||
msgid "Default restriction setting for all variations. Only allow quantities defined in packages above."
|
||||
msgstr "Paramètre de restriction par défaut pour toutes les variations. Autoriser uniquement les quantités définies dans les forfaits ci-dessus."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:90
|
||||
msgid "Minimum Quantity"
|
||||
msgstr "Quantité minimale"
|
||||
|
||||
Binary file not shown.
@@ -3,10 +3,10 @@
|
||||
# This file is distributed under the GPL v2 or later.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: WooCommerce Tier and Package Prices 1.1.21\n"
|
||||
"Project-Id-Version: WooCommerce Tier and Package Prices 1.2.7\n"
|
||||
"Report-Msgid-Bugs-To: https://src.bundespruefstelle.ch/wc-tier-package-prices\n"
|
||||
"POT-Creation-Date: 2025-12-23 00:00+0000\n"
|
||||
"PO-Revision-Date: 2025-12-23 00:00+0000\n"
|
||||
"POT-Creation-Date: 2025-12-30 00:00+0000\n"
|
||||
"PO-Revision-Date: 2025-12-30 00:00+0000\n"
|
||||
"Last-Translator: Marco Graetsch\n"
|
||||
"Language-Team: Italian (Switzerland)\n"
|
||||
"Language: it_CH\n"
|
||||
@@ -152,6 +152,26 @@ msgstr "Aggiungi pacchetto"
|
||||
msgid "Only allow quantities defined in packages above"
|
||||
msgstr "Consenti solo le quantità definite nei pacchetti sopra"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:42
|
||||
msgid "Default Tier & Package Pricing for All Variations"
|
||||
msgstr "Prezzi a scaglioni e pacchetti predefiniti per tutte le variazioni"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:43
|
||||
msgid "Set default pricing for all variations. Individual variations can override these defaults with their own specific pricing."
|
||||
msgstr "Imposta i prezzi predefiniti per tutte le variazioni. Le singole variazioni possono sovrascrivere questi valori predefiniti con i propri prezzi specifici."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:44
|
||||
msgid "Configure default tier and package pricing here. All variations will inherit these settings unless they define their own specific pricing."
|
||||
msgstr "Configura qui i prezzi a scaglioni e pacchetti predefiniti. Tutte le variazioni erediteranno queste impostazioni a meno che non definiscano i propri prezzi specifici."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:87
|
||||
msgid "Restrict to Package Quantities (Default)"
|
||||
msgstr "Limita alle quantità dei pacchetti (predefinito)"
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:88
|
||||
msgid "Default restriction setting for all variations. Only allow quantities defined in packages above."
|
||||
msgstr "Impostazione di restrizione predefinita per tutte le variazioni. Consenti solo le quantità definite nei pacchetti sopra."
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:90
|
||||
msgid "Minimum Quantity"
|
||||
msgstr "Quantità minima"
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
# This file is distributed under the GPL v2 or later.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: WooCommerce Tier and Package Prices 1.1.6\n"
|
||||
"Project-Id-Version: WooCommerce Tier and Package Prices 1.2.7\n"
|
||||
"Report-Msgid-Bugs-To: https://src.bundespruefstelle.ch/wc-tier-package-prices\n"
|
||||
"POT-Creation-Date: 2025-12-21 00:00+0000\n"
|
||||
"POT-Creation-Date: 2025-12-30 00:00+0000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
@@ -132,6 +132,26 @@ msgstr ""
|
||||
msgid "Only allow quantities defined in packages above"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:42
|
||||
msgid "Default Tier & Package Pricing for All Variations"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:43
|
||||
msgid "Set default pricing for all variations. Individual variations can override these defaults with their own specific pricing."
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:44
|
||||
msgid "Configure default tier and package pricing here. All variations will inherit these settings unless they define their own specific pricing."
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:87
|
||||
msgid "Restrict to Package Quantities (Default)"
|
||||
msgstr ""
|
||||
|
||||
#: includes/class-wc-tpp-product-meta.php:88
|
||||
msgid "Default restriction setting for all variations. Only allow quantities defined in packages above."
|
||||
msgstr ""
|
||||
|
||||
#: templates/admin/tier-row.twig:9
|
||||
msgid "Minimum Quantity"
|
||||
msgstr ""
|
||||
|
||||
BIN
releases/wc-tier-and-package-prices-1.2.4.zip
Normal file
BIN
releases/wc-tier-and-package-prices-1.2.4.zip
Normal file
Binary file not shown.
1
releases/wc-tier-and-package-prices-1.2.4.zip.md5
Normal file
1
releases/wc-tier-and-package-prices-1.2.4.zip.md5
Normal file
@@ -0,0 +1 @@
|
||||
abd9cb934494f7053c19a0a022d5717f wc-tier-and-package-prices-1.2.4.zip
|
||||
1
releases/wc-tier-and-package-prices-1.2.4.zip.sha256
Normal file
1
releases/wc-tier-and-package-prices-1.2.4.zip.sha256
Normal file
@@ -0,0 +1 @@
|
||||
976bd9bf2cdc5bbf34a65160bc1b42f74cbff71d39c634a042efd59aa90a13d0 wc-tier-and-package-prices-1.2.4.zip
|
||||
BIN
releases/wc-tier-and-package-prices-1.2.5.zip
Normal file
BIN
releases/wc-tier-and-package-prices-1.2.5.zip
Normal file
Binary file not shown.
1
releases/wc-tier-and-package-prices-1.2.5.zip.md5
Normal file
1
releases/wc-tier-and-package-prices-1.2.5.zip.md5
Normal file
@@ -0,0 +1 @@
|
||||
61eafd6c2fdd1468c486efe0c6e3bfa4 wc-tier-and-package-prices-1.2.5.zip
|
||||
1
releases/wc-tier-and-package-prices-1.2.5.zip.sha256
Normal file
1
releases/wc-tier-and-package-prices-1.2.5.zip.sha256
Normal file
@@ -0,0 +1 @@
|
||||
4f6d637713511db061dd2db5f948b846eb48c343d9b8823299b85038ccca6a6e wc-tier-and-package-prices-1.2.5.zip
|
||||
BIN
releases/wc-tier-and-package-prices-1.2.6.zip
Normal file
BIN
releases/wc-tier-and-package-prices-1.2.6.zip
Normal file
Binary file not shown.
1
releases/wc-tier-and-package-prices-1.2.6.zip.md5
Normal file
1
releases/wc-tier-and-package-prices-1.2.6.zip.md5
Normal file
@@ -0,0 +1 @@
|
||||
b2c862fbad94f42f0756fb496a1dd920 wc-tier-and-package-prices-1.2.6.zip
|
||||
1
releases/wc-tier-and-package-prices-1.2.6.zip.sha256
Normal file
1
releases/wc-tier-and-package-prices-1.2.6.zip.sha256
Normal file
@@ -0,0 +1 @@
|
||||
19a00c7fc2f42326f52d2da063766abd1c0b47d1701b9050c018bfb2bafae6f6 wc-tier-and-package-prices-1.2.6.zip
|
||||
BIN
releases/wc-tier-and-package-prices-1.2.7.zip
Normal file
BIN
releases/wc-tier-and-package-prices-1.2.7.zip
Normal file
Binary file not shown.
1
releases/wc-tier-and-package-prices-1.2.7.zip.md5
Normal file
1
releases/wc-tier-and-package-prices-1.2.7.zip.md5
Normal file
@@ -0,0 +1 @@
|
||||
b52aec2e42c894a1949b5e5898105cf1 wc-tier-and-package-prices-1.2.7.zip
|
||||
1
releases/wc-tier-and-package-prices-1.2.7.zip.sha256
Normal file
1
releases/wc-tier-and-package-prices-1.2.7.zip.sha256
Normal file
@@ -0,0 +1 @@
|
||||
7ae87ca85f7799ed716d3a81be8977908fadb33260dbc565f6b0d39188c8b025 wc-tier-and-package-prices-1.2.7.zip
|
||||
BIN
releases/wc-tier-and-package-prices-1.2.8.zip
Normal file
BIN
releases/wc-tier-and-package-prices-1.2.8.zip
Normal file
Binary file not shown.
1
releases/wc-tier-and-package-prices-1.2.8.zip.md5
Normal file
1
releases/wc-tier-and-package-prices-1.2.8.zip.md5
Normal file
@@ -0,0 +1 @@
|
||||
d412c85ef32b2e79e17227749265919f wc-tier-and-package-prices-1.2.8.zip
|
||||
1
releases/wc-tier-and-package-prices-1.2.8.zip.sha256
Normal file
1
releases/wc-tier-and-package-prices-1.2.8.zip.sha256
Normal file
@@ -0,0 +1 @@
|
||||
0c47e2a966c485b377beaffb56703a130158a15e7ffe9d95b43dea84f9229e9c wc-tier-and-package-prices-1.2.8.zip
|
||||
BIN
releases/wc-tier-and-package-prices-1.2.9.zip
Normal file
BIN
releases/wc-tier-and-package-prices-1.2.9.zip
Normal file
Binary file not shown.
1
releases/wc-tier-and-package-prices-1.2.9.zip.md5
Normal file
1
releases/wc-tier-and-package-prices-1.2.9.zip.md5
Normal file
@@ -0,0 +1 @@
|
||||
073fbf114a32d99cd8ced683a1efa19c wc-tier-and-package-prices-1.2.9.zip
|
||||
1
releases/wc-tier-and-package-prices-1.2.9.zip.sha256
Normal file
1
releases/wc-tier-and-package-prices-1.2.9.zip.sha256
Normal file
@@ -0,0 +1 @@
|
||||
00d2568e9acfd7fc05c88b9048a6a281d007b55dec9c4c7a4a55cb515e013e97 wc-tier-and-package-prices-1.2.9.zip
|
||||
@@ -21,7 +21,7 @@
|
||||
<input type="text"
|
||||
name="{{ name_prefix }}[{{ index|esc_attr }}][price]"
|
||||
value="{{ package.price|default('')|esc_attr }}"
|
||||
placeholder="{{ 'e.g., 99.99'|__('wc-tier-package-prices') }}"
|
||||
placeholder="{{ 'e.g., 99.99 ' ~ currency_symbol }}"
|
||||
class="short wc_input_price">
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<input type="text"
|
||||
name="{{ name_prefix }}[{{ index|esc_attr }}][price]"
|
||||
value="{{ tier.price|default('')|esc_attr }}"
|
||||
placeholder="{{ 'e.g., 9.99'|__('wc-tier-package-prices') }}"
|
||||
placeholder="{{ 'e.g., 9.99 ' ~ currency_symbol }}"
|
||||
class="short wc_input_price">
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Plugin Name: WooCommerce Tier and Package Prices
|
||||
* Plugin URI: https://src.bundespruefstelle.ch/magdev/wc-tier-package-prices
|
||||
* Description: Add tier pricing and package prices to WooCommerce products with configurable quantities at fixed prices
|
||||
* Version: 1.2.4
|
||||
* Version: 1.2.9
|
||||
* Author: Marco Graetsch
|
||||
* Author URI: https://src.bundespruefstelle.ch/magdev
|
||||
* Text Domain: wc-tier-package-prices
|
||||
@@ -23,7 +23,7 @@ if (!defined('ABSPATH')) {
|
||||
|
||||
// Define plugin constants
|
||||
if (!defined('WC_TPP_VERSION')) {
|
||||
define('WC_TPP_VERSION', '1.2.4');
|
||||
define('WC_TPP_VERSION', '1.2.9');
|
||||
}
|
||||
if (!defined('WC_TPP_PLUGIN_DIR')) {
|
||||
define('WC_TPP_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
||||
|
||||
Reference in New Issue
Block a user