|
|
|
@@ -546,11 +546,13 @@ When modifying admin input fields in Twig templates, use WooCommerce's standard
|
|
|
|
|
**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)
|
|
|
|
@@ -559,6 +561,7 @@ When modifying admin input fields in Twig templates, use WooCommerce's standard
|
|
|
|
|
**Solution Patterns:**
|
|
|
|
|
|
|
|
|
|
**For Table Styling:**
|
|
|
|
|
|
|
|
|
|
```css
|
|
|
|
|
/* ❌ This will likely be overridden */
|
|
|
|
|
.wc-tpp-tiers-table {
|
|
|
|
@@ -582,6 +585,7 @@ When modifying admin input fields in Twig templates, use WooCommerce's standard
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**For Float-Based Layouts:**
|
|
|
|
|
|
|
|
|
|
```css
|
|
|
|
|
/* ❌ Float positioning is hard to control precisely */
|
|
|
|
|
.woocommerce-help-tip {
|
|
|
|
@@ -606,6 +610,7 @@ label[for="_wc_tpp_restrict_to_packages"] {
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**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
|
|
|
|
@@ -613,6 +618,7 @@ label[for="_wc_tpp_restrict_to_packages"] {
|
|
|
|
|
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
|
|
|
|
@@ -809,6 +815,102 @@ WooCommerce has different hooks for different product types in the admin product
|
|
|
|
|
|
|
|
|
|
**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
|
|
|
|
|