You've already forked wc-tier-and-package-prices
Fixed critical plugin activation error that was preventing the plugin from being activated on WordPress 6.9.x and WooCommerce 10.x. The issue was introduced in v1.1.3 when admin classes were still being instantiated immediately at file include time, before WooCommerce was loaded. While v1.1.6 fixed this for Frontend and Cart classes, the Admin and Product Meta classes were missed. Critical Fix: - Removed immediate instantiation from WC_TPP_Admin class - Removed immediate instantiation from WC_TPP_Product_Meta class - Both classes now instantiated via woocommerce_loaded hook - Ensures all WooCommerce hooks are available before registration Technical Changes: - Removed "new WC_TPP_Admin();" from class-wc-tpp-admin.php - Removed "new WC_TPP_Product_Meta();" from class-wc-tpp-product-meta.php - Added both classes to init_classes() method in main plugin file - All four main classes now follow consistent initialization pattern Impact: - Plugin now activates correctly on all WordPress/WooCommerce versions - Resolves fatal errors during plugin activation - Last working version was v1.1.2, now fixed in v1.1.8 Updated Files: - includes/class-wc-tpp-admin.php (removed auto-instantiation) - includes/class-wc-tpp-product-meta.php (removed auto-instantiation) - wc-tier-and-package-prices.php (version 1.1.8, init_classes updated) - composer.json (version 1.1.8) - CHANGELOG.md (v1.1.8 section added) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
170 lines
6.3 KiB
PHP
170 lines
6.3 KiB
PHP
<?php
|
|
/**
|
|
* Product meta boxes for tier and package pricing
|
|
*/
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
class WC_TPP_Product_Meta {
|
|
|
|
public function __construct() {
|
|
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'));
|
|
}
|
|
|
|
public function add_tier_pricing_fields() {
|
|
global $post;
|
|
?>
|
|
<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>
|
|
|
|
<div 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);
|
|
}
|
|
?>
|
|
</div>
|
|
|
|
<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;
|
|
?>
|
|
<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>
|
|
|
|
<div 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);
|
|
}
|
|
?>
|
|
</div>
|
|
|
|
<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', 'wc-tier-package-prices'),
|
|
'description' => __('Only allow quantities defined in packages above', 'wc-tier-package-prices'),
|
|
'desc_tip' => true,
|
|
));
|
|
?>
|
|
</div>
|
|
|
|
<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>
|
|
<?php
|
|
}
|
|
|
|
private function render_tier_row($index, $tier) {
|
|
WC_TPP_Template_Loader::get_instance()->display('admin/tier-row.twig', array(
|
|
'index' => $index,
|
|
'tier' => $tier
|
|
));
|
|
}
|
|
|
|
private function render_package_row($index, $package) {
|
|
WC_TPP_Template_Loader::get_instance()->display('admin/package-row.twig', array(
|
|
'index' => $index,
|
|
'package' => $package
|
|
));
|
|
}
|
|
|
|
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'];
|
|
});
|
|
update_post_meta($post_id, '_wc_tpp_tiers', $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'];
|
|
});
|
|
update_post_meta($post_id, '_wc_tpp_packages', $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);
|
|
}
|
|
}
|