ID); if (!$product || !$product->is_type('variable')) { return; } ?>

ID, '_wc_tpp_tiers', true); if (!is_array($tiers)) { $tiers = array(); } foreach ($tiers as $index => $tier) { $this->render_tier_row($index, $tier); } ?>

ID, '_wc_tpp_packages', true); if (!is_array($packages)) { $packages = array(); } foreach ($packages as $index => $package) { $this->render_package_row($index, $package); } ?>

'_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, )); ?>
ID); if ($product && $product->is_type('variable')) { return; } ?>

ID, '_wc_tpp_tiers', true); if (!is_array($tiers)) { $tiers = array(); } foreach ($tiers as $index => $tier) { $this->render_tier_row($index, $tier); } ?>

ID); if ($product && $product->is_type('variable')) { return; } ?>

ID, '_wc_tpp_packages', true); if (!is_array($packages)) { $packages = array(); } foreach ($packages as $index => $package) { $this->render_package_row($index, $package); } ?>

'_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, )); ?>
display('admin/tier-row.twig', array( 'index' => $index, '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, 'currency_symbol' => get_woocommerce_currency_symbol() )); } /** * 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(); } ?>

$tier) : ?> render_variation_tier_row($loop, $index, $tier); ?>

$package) : ?> render_variation_package_row($loop, $index, $package); ?>
'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'), 'desc_tip' => true, 'value' => $restrict, 'cbvalue' => 'yes', 'wrapper_class' => 'form-row form-row-full' )); ?>
display('admin/tier-row.twig', array( 'index' => $index, 'tier' => $tier, 'field_prefix' => 'wc_tpp_tiers[' . $loop . ']', 'currency_symbol' => get_woocommerce_currency_symbol() )); } /** * 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, 'field_prefix' => 'wc_tpp_packages[' . $loop . ']', 'currency_symbol' => get_woocommerce_currency_symbol() )); } 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']), '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']; }); // 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'])) { $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']; }); // 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'; update_post_meta($post_id, '_wc_tpp_restrict_to_packages', $restrict_to_packages); } /** * 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 $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( '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']; }); } // 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 $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( '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']; }); } // 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'); } // 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'); } } } new WC_TPP_Product_Meta(); }