2025-12-21 04:56:50 +01:00
< ? php
/**
* Product meta boxes for tier and package pricing
*/
if ( ! defined ( 'ABSPATH' )) {
exit ;
}
Release version 1.1.13 - Critical class redeclaration fixes
Fixed critical class redeclaration errors affecting all plugin functionality
in version 1.1.12. All plugin component classes now properly guarded.
**CRITICAL FIXES:**
- Plugin completely non-functional in v1.1.12 (no settings, no frontend, no backend)
- Fatal errors for WC_TPP_Admin, WC_TPP_Product_Meta, WC_TPP_Frontend, WC_TPP_Cart, WC_TPP_Settings classes
- All classes now wrapped in class_exists() checks
**Files Modified:**
- includes/class-wc-tpp-admin.php
- includes/class-wc-tpp-product-meta.php
- includes/class-wc-tpp-frontend.php
- includes/class-wc-tpp-cart.php
- includes/class-wc-tpp-settings.php
**Technical Details:**
- Completes comprehensive redeclaration protection started in v1.1.9-1.1.12
- All 2 functions, 4 constants, and 6 classes now protected
- Plugin activates successfully and all features functional
- Settings page, product meta boxes, frontend display, cart integration all working
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 19:02:18 +01:00
if ( ! class_exists ( 'WC_TPP_Product_Meta' )) {
class WC_TPP_Product_Meta {
2025-12-21 04:56:50 +01:00
public function __construct () {
2025-12-29 20:02:03 +01:00
// Simple product hooks
2025-12-21 04:56:50 +01:00
add_action ( 'woocommerce_product_options_pricing' , array ( $this , 'add_tier_pricing_fields' ));
add_action ( 'woocommerce_product_options_pricing' , array ( $this , 'add_package_pricing_fields' ));
add_action ( 'woocommerce_process_product_meta' , array ( $this , 'save_tier_package_fields' ));
2025-12-29 20:02:03 +01:00
2025-12-30 00:38:29 +01:00
// Variable product parent hooks (for default pricing)
2025-12-30 00:48:46 +01:00
// 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' ));
2025-12-30 00:38:29 +01:00
2025-12-29 20:02:03 +01:00
// 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 );
2025-12-21 04:56:50 +01:00
}
2025-12-30 00:38:29 +01:00
/**
* 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>
2025-12-30 05:02:50 +01:00
< th >< ? php printf ( esc_html__ ( 'Price (%s)' , 'wc-tier-package-prices' ), get_woocommerce_currency_symbol ()); ?> </th>
2025-12-30 00:38:29 +01:00
< 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>
2025-12-30 05:02:50 +01:00
< th >< ? php printf ( esc_html__ ( 'Price (%s)' , 'wc-tier-package-prices' ), get_woocommerce_currency_symbol ()); ?> </th>
2025-12-30 00:38:29 +01:00
< 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
}
2025-12-21 04:56:50 +01:00
public function add_tier_pricing_fields () {
global $post ;
2025-12-30 00:38:29 +01:00
// 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 ;
}
2025-12-21 04:56:50 +01:00
?>
< div class = " options_group wc-tpp-tier-pricing " >
< p class = " form-field " >
< label >< ? php _e ( 'Tier Pricing' , 'wc-tier-package-prices' ); ?> </label>
< span class = " description " >< ? php _e ( 'Set quantity-based pricing tiers. Customers get discounted prices when buying in larger quantities.' , 'wc-tier-package-prices' ); ?> </span>
</ p >
2025-12-29 20:02:03 +01:00
< table class = " widefat wc-tpp-tiers-table " >
< thead >
< tr >
< th >< ? php _e ( 'Min Quantity' , 'wc-tier-package-prices' ); ?> </th>
2025-12-30 05:02:50 +01:00
< th >< ? php printf ( esc_html__ ( 'Price (%s)' , 'wc-tier-package-prices' ), get_woocommerce_currency_symbol ()); ?> </th>
2025-12-29 20:02:03 +01:00
< 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 ();
}
2025-12-21 04:56:50 +01:00
2025-12-29 20:02:03 +01:00
foreach ( $tiers as $index => $tier ) {
$this -> render_tier_row ( $index , $tier );
}
?>
</ tbody >
</ table >
2025-12-21 04:56:50 +01:00
< p class = " form-field " >
< button type = " button " class = " button wc-tpp-add-tier " >< ? php _e ( 'Add Tier' , 'wc-tier-package-prices' ); ?> </button>
</ p >
</ div >
< ? php
}
public function add_package_pricing_fields () {
global $post ;
2025-12-30 00:38:29 +01:00
// 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 ;
}
2025-12-21 04:56:50 +01:00
?>
< div class = " options_group wc-tpp-package-pricing " >
< p class = " form-field " >
< label >< ? php _e ( 'Package Pricing' , 'wc-tier-package-prices' ); ?> </label>
< span class = " description " >< ? php _e ( 'Set fixed-price packages with specific quantities. For example: 10 pieces for $50, 25 pieces for $100.' , 'wc-tier-package-prices' ); ?> </span>
</ p >
2025-12-29 20:02:03 +01:00
< table class = " widefat wc-tpp-packages-table " >
< thead >
< tr >
< th >< ? php _e ( 'Quantity' , 'wc-tier-package-prices' ); ?> </th>
2025-12-30 05:02:50 +01:00
< th >< ? php printf ( esc_html__ ( 'Price (%s)' , 'wc-tier-package-prices' ), get_woocommerce_currency_symbol ()); ?> </th>
2025-12-29 20:02:03 +01:00
< 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 ();
}
2025-12-21 04:56:50 +01:00
2025-12-29 20:02:03 +01:00
foreach ( $packages as $index => $package ) {
$this -> render_package_row ( $index , $package );
}
?>
</ tbody >
</ table >
2025-12-21 04:56:50 +01:00
< p class = " form-field " >
< button type = " button " class = " button wc-tpp-add-package " >< ? php _e ( 'Add Package' , 'wc-tier-package-prices' ); ?> </button>
</ p >
2025-12-21 15:54:04 +01:00
< ? php
woocommerce_wp_checkbox ( array (
'id' => '_wc_tpp_restrict_to_packages' ,
'label' => __ ( 'Restrict to Package Quantities' , 'wc-tier-package-prices' ),
'description' => __ ( 'Only allow quantities defined in packages above' , 'wc-tier-package-prices' ),
'desc_tip' => true ,
));
?>
2025-12-21 04:56:50 +01:00
</ div >
< script type = " text/html " id = " wc-tpp-tier-row-template " >
2025-12-22 00:15:48 +01:00
< ? php $this -> render_tier_row ( '{{INDEX}}' , array ( 'min_qty' => '' , 'price' => '' , 'label' => '' )); ?>
2025-12-21 04:56:50 +01:00
</ script >
< script type = " text/html " id = " wc-tpp-package-row-template " >
< ? php $this -> render_package_row ( '{{INDEX}}' , array ( 'qty' => '' , 'price' => '' , 'label' => '' )); ?>
</ script >
< ? php
}
private function render_tier_row ( $index , $tier ) {
WC_TPP_Template_Loader :: get_instance () -> display ( 'admin/tier-row.twig' , array (
'index' => $index ,
2025-12-30 01:23:55 +01:00
'tier' => $tier ,
'currency_symbol' => get_woocommerce_currency_symbol ()
2025-12-21 04:56:50 +01:00
));
}
private function render_package_row ( $index , $package ) {
WC_TPP_Template_Loader :: get_instance () -> display ( 'admin/package-row.twig' , array (
'index' => $index ,
2025-12-30 01:23:55 +01:00
'package' => $package ,
'currency_symbol' => get_woocommerce_currency_symbol ()
2025-12-21 04:56:50 +01:00
));
}
2025-12-29 20:02:03 +01:00
/**
* Add tier and package pricing fields to product variations
*
* @ param int $loop Position in the loop
* @ param array $variation_data Variation data
* @ param WP_Post $variation Variation post object
*/
public function add_variation_pricing_fields ( $loop , $variation_data , $variation ) {
$variation_id = $variation -> ID ;
// Retrieve variation-specific data
$tiers = get_post_meta ( $variation_id , '_wc_tpp_tiers' , true );
$packages = get_post_meta ( $variation_id , '_wc_tpp_packages' , true );
$restrict = get_post_meta ( $variation_id , '_wc_tpp_restrict_to_packages' , true );
if ( ! is_array ( $tiers )) {
$tiers = array ();
}
if ( ! is_array ( $packages )) {
$packages = array ();
}
?>
< div class = " form-row form-row-full wc-tpp-variation-pricing " data - variation - loop = " <?php echo esc_attr( $loop ); ?> " >
< h4 >< ? php _e ( 'Tier & Package Pricing' , 'wc-tier-package-prices' ); ?> </h4>
<!-- Tier Pricing Section -->
< div class = " wc-tpp-variation-tiers " >
< 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>
2025-12-30 05:02:50 +01:00
< th >< ? php printf ( esc_html__ ( 'Price (%s)' , 'wc-tier-package-prices' ), get_woocommerce_currency_symbol ()); ?> </th>
2025-12-29 20:02:03 +01:00
< th >< ? php _e ( 'Label (optional)' , 'wc-tier-package-prices' ); ?> </th>
< th ></ th >
</ tr >
</ thead >
< tbody class = " wc-tpp-tiers-container " >
< ? php foreach ( $tiers as $index => $tier ) : ?>
< ? php $this -> render_variation_tier_row ( $loop , $index , $tier ); ?>
< ? php endforeach ; ?>
</ tbody >
</ table >
< button type = " button " class = " button wc-tpp-add-tier " data - loop = " <?php echo esc_attr( $loop ); ?> " >
< ? php _e ( 'Add Tier' , 'wc-tier-package-prices' ); ?>
</ button >
</ div >
<!-- Package Pricing Section -->
< div class = " wc-tpp-variation-packages " style = " margin-top: 15px; " >
< 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>
2025-12-30 05:02:50 +01:00
< th >< ? php printf ( esc_html__ ( 'Price (%s)' , 'wc-tier-package-prices' ), get_woocommerce_currency_symbol ()); ?> </th>
2025-12-29 20:02:03 +01:00
< th >< ? php _e ( 'Label (optional)' , 'wc-tier-package-prices' ); ?> </th>
< th ></ th >
</ tr >
</ thead >
< tbody class = " wc-tpp-packages-container " >
< ? php foreach ( $packages as $index => $package ) : ?>
< ? php $this -> render_variation_package_row ( $loop , $index , $package ); ?>
< ? php endforeach ; ?>
</ tbody >
</ table >
< button type = " button " class = " button wc-tpp-add-package " data - loop = " <?php echo esc_attr( $loop ); ?> " >
< ? php _e ( 'Add Package' , 'wc-tier-package-prices' ); ?>
</ button >
</ div >
<!-- Restriction Checkbox -->
< div style = " margin-top: 15px; " >
< ? php
woocommerce_wp_checkbox ( array (
'id' => 'wc_tpp_restrict_to_packages_' . $loop ,
'name' => 'wc_tpp_restrict_to_packages[' . $loop . ']' ,
'label' => __ ( 'Restrict to Package Quantities' , 'wc-tier-package-prices' ),
'description' => __ ( 'Only allow quantities defined in packages above' , 'wc-tier-package-prices' ),
2025-12-29 21:06:25 +01:00
'desc_tip' => true ,
2025-12-29 20:53:23 +01:00
'value' => $restrict ,
2025-12-29 20:02:03 +01:00
'cbvalue' => 'yes' ,
'wrapper_class' => 'form-row form-row-full'
));
?>
</ div >
<!-- Templates for JavaScript -->
< script type = " text/html " id = " wc-tpp-variation-tier-row-template-<?php echo esc_attr( $loop ); ?> " >
< ? php $this -> render_variation_tier_row ( $loop , '{{INDEX}}' , array ( 'min_qty' => '' , 'price' => '' , 'label' => '' )); ?>
</ script >
< script type = " text/html " id = " wc-tpp-variation-package-row-template-<?php echo esc_attr( $loop ); ?> " >
< ? php $this -> render_variation_package_row ( $loop , '{{INDEX}}' , array ( 'qty' => '' , 'price' => '' , 'label' => '' )); ?>
</ script >
</ div >
< ? php
}
/**
* Render a tier row for variations
*
* @ param int $loop Variation loop index
* @ param int $index Tier index
* @ param array $tier Tier data
*/
private function render_variation_tier_row ( $loop , $index , $tier ) {
WC_TPP_Template_Loader :: get_instance () -> display ( 'admin/tier-row.twig' , array (
'index' => $index ,
'tier' => $tier ,
2025-12-30 01:23:55 +01:00
'field_prefix' => 'wc_tpp_tiers[' . $loop . ']' ,
'currency_symbol' => get_woocommerce_currency_symbol ()
2025-12-29 20:02:03 +01:00
));
}
/**
* Render a package row for variations
*
* @ param int $loop Variation loop index
* @ param int $index Package index
* @ param array $package Package data
*/
private function render_variation_package_row ( $loop , $index , $package ) {
WC_TPP_Template_Loader :: get_instance () -> display ( 'admin/package-row.twig' , array (
'index' => $index ,
'package' => $package ,
2025-12-30 01:23:55 +01:00
'field_prefix' => 'wc_tpp_packages[' . $loop . ']' ,
'currency_symbol' => get_woocommerce_currency_symbol ()
2025-12-29 20:02:03 +01:00
));
}
2025-12-21 04:56:50 +01:00
public function save_tier_package_fields ( $post_id ) {
// Verify nonce for security
if ( ! isset ( $_POST [ 'woocommerce_meta_nonce' ]) || ! wp_verify_nonce ( $_POST [ 'woocommerce_meta_nonce' ], 'woocommerce_save_data' )) {
return ;
}
// Check user permissions
if ( ! current_user_can ( 'edit_post' , $post_id )) {
return ;
}
// Avoid auto-save
if ( defined ( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return ;
}
// Save tier pricing
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 (
'min_qty' => absint ( $tier [ 'min_qty' ]),
2025-12-22 00:15:48 +01:00
'price' => wc_format_decimal ( $tier [ 'price' ]),
'label' => sanitize_text_field ( $tier [ 'label' ] ? ? '' )
2025-12-21 04:56:50 +01:00
);
}
}
// Sort by minimum quantity
usort ( $tiers , function ( $a , $b ) {
return $a [ 'min_qty' ] - $b [ 'min_qty' ];
});
2025-12-30 01:23:55 +01:00
// 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' );
}
2025-12-21 04:56:50 +01:00
} else {
delete_post_meta ( $post_id , '_wc_tpp_tiers' );
}
// Save package pricing
if ( isset ( $_POST [ '_wc_tpp_packages' ])) {
$packages = array ();
foreach ( $_POST [ '_wc_tpp_packages' ] as $package ) {
if ( ! empty ( $package [ 'qty' ]) && ! empty ( $package [ 'price' ])) {
$packages [] = array (
'qty' => absint ( $package [ 'qty' ]),
'price' => wc_format_decimal ( $package [ 'price' ]),
'label' => sanitize_text_field ( $package [ 'label' ])
);
}
}
// Sort by quantity
usort ( $packages , function ( $a , $b ) {
return $a [ 'qty' ] - $b [ 'qty' ];
});
2025-12-30 01:23:55 +01:00
// 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' );
}
2025-12-21 04:56:50 +01:00
} else {
delete_post_meta ( $post_id , '_wc_tpp_packages' );
}
2025-12-21 15:54:04 +01:00
// Save package quantity restriction setting
$restrict_to_packages = isset ( $_POST [ '_wc_tpp_restrict_to_packages' ]) ? 'yes' : 'no' ;
update_post_meta ( $post_id , '_wc_tpp_restrict_to_packages' , $restrict_to_packages );
2025-12-21 04:56:50 +01:00
}
2025-12-29 20:02:03 +01:00
/**
* Save tier and package pricing for variations
*
* @ param int $variation_id Variation ID
* @ param int $loop Position in loop
*/
public function save_variation_pricing_fields ( $variation_id , $loop ) {
// Security check
if ( ! current_user_can ( 'edit_products' )) {
return ;
}
// Save tier pricing for this variation
2025-12-30 05:02:50 +01:00
$tiers = array ();
if ( isset ( $_POST [ 'wc_tpp_tiers' ][ $loop ]) && is_array ( $_POST [ 'wc_tpp_tiers' ][ $loop ])) {
2025-12-29 20:02:03 +01:00
foreach ( $_POST [ 'wc_tpp_tiers' ][ $loop ] as $tier ) {
if ( ! empty ( $tier [ 'min_qty' ]) && ! empty ( $tier [ 'price' ])) {
$tiers [] = array (
'min_qty' => absint ( $tier [ 'min_qty' ]),
'price' => wc_format_decimal ( $tier [ 'price' ]),
'label' => sanitize_text_field ( $tier [ 'label' ] ? ? '' )
);
}
}
// Sort by minimum quantity
usort ( $tiers , function ( $a , $b ) {
return $a [ 'min_qty' ] - $b [ 'min_qty' ];
});
2025-12-30 05:02:50 +01:00
}
// Always update or delete based on whether we have valid tiers
if ( ! empty ( $tiers )) {
update_post_meta ( $variation_id , '_wc_tpp_tiers' , $tiers );
2025-12-29 20:02:03 +01:00
} else {
delete_post_meta ( $variation_id , '_wc_tpp_tiers' );
}
// Save package pricing for this variation
2025-12-30 05:02:50 +01:00
$packages = array ();
if ( isset ( $_POST [ 'wc_tpp_packages' ][ $loop ]) && is_array ( $_POST [ 'wc_tpp_packages' ][ $loop ])) {
2025-12-29 20:02:03 +01:00
foreach ( $_POST [ 'wc_tpp_packages' ][ $loop ] as $package ) {
if ( ! empty ( $package [ 'qty' ]) && ! empty ( $package [ 'price' ])) {
$packages [] = array (
'qty' => absint ( $package [ 'qty' ]),
'price' => wc_format_decimal ( $package [ 'price' ]),
'label' => sanitize_text_field ( $package [ 'label' ] ? ? '' )
);
}
}
// Sort by quantity
usort ( $packages , function ( $a , $b ) {
return $a [ 'qty' ] - $b [ 'qty' ];
});
2025-12-30 05:02:50 +01:00
}
// Always update or delete based on whether we have valid packages
if ( ! empty ( $packages )) {
update_post_meta ( $variation_id , '_wc_tpp_packages' , $packages );
2025-12-29 20:02:03 +01:00
} else {
delete_post_meta ( $variation_id , '_wc_tpp_packages' );
}
// Save restriction setting for this variation
if ( isset ( $_POST [ 'wc_tpp_restrict_to_packages' ][ $loop ]) && $_POST [ 'wc_tpp_restrict_to_packages' ][ $loop ] === 'yes' ) {
update_post_meta ( $variation_id , '_wc_tpp_restrict_to_packages' , 'yes' );
} else {
delete_post_meta ( $variation_id , '_wc_tpp_restrict_to_packages' );
}
}
2025-12-21 04:56:50 +01:00
}
2025-12-22 19:32:47 +01:00
new WC_TPP_Product_Meta ();
Release version 1.1.13 - Critical class redeclaration fixes
Fixed critical class redeclaration errors affecting all plugin functionality
in version 1.1.12. All plugin component classes now properly guarded.
**CRITICAL FIXES:**
- Plugin completely non-functional in v1.1.12 (no settings, no frontend, no backend)
- Fatal errors for WC_TPP_Admin, WC_TPP_Product_Meta, WC_TPP_Frontend, WC_TPP_Cart, WC_TPP_Settings classes
- All classes now wrapped in class_exists() checks
**Files Modified:**
- includes/class-wc-tpp-admin.php
- includes/class-wc-tpp-product-meta.php
- includes/class-wc-tpp-frontend.php
- includes/class-wc-tpp-cart.php
- includes/class-wc-tpp-settings.php
**Technical Details:**
- Completes comprehensive redeclaration protection started in v1.1.9-1.1.12
- All 2 functions, 4 constants, and 6 classes now protected
- Plugin activates successfully and all features functional
- Settings page, product meta boxes, frontend display, cart integration all working
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 19:02:18 +01:00
}