Files
wc-tier-and-package-prices/includes/class-wc-tpp-product-meta.php

174 lines
6.3 KiB
PHP
Raw Normal View History

<?php
/**
* Product meta boxes for tier and package pricing
*/
if (!defined('ABSPATH')) {
exit;
}
if (!class_exists('WC_TPP_Product_Meta')) {
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">
Release version 1.1.7 - Enhanced user experience features Added three new customer-facing features to improve product page interaction and tier pricing functionality. Features: - Optional text labels for tier pricing (similar to package labels) - Clickable tier pricing table rows to auto-populate quantity field - Add to Cart button auto-disables when quantity is 0 or less Enhanced User Experience: - Tier pricing rows now clickable with cursor pointer and hover animation - Clicking tier row sets quantity and smoothly scrolls to quantity field - Add to Cart button shows disabled state with reduced opacity - Tier labels display below quantity in italic gray text Technical Changes: - Added optional 'label' field to tier pricing admin meta box - Updated tier save logic to include label field (sanitized) - Enhanced tier pricing frontend template to display labels - Added click handler for tier pricing rows in frontend.js - Added updateAddToCartButton() function to manage button state - CSS: .wc-tpp-tier-label styling for tier labels - CSS: Clickable cursor and hover transform for tier rows - CSS: Disabled button styling (.single_add_to_cart_button:disabled) Updated Files: - templates/admin/tier-row.twig (added label field) - includes/class-wc-tpp-product-meta.php (save label, template update) - templates/frontend/tier-pricing-table.twig (display labels) - assets/js/frontend.js (tier row clicks, button disable logic) - assets/css/frontend.css (tier label style, clickable rows, disabled button) - wc-tier-and-package-prices.php (version 1.1.7) - composer.json (version 1.1.7) - CHANGELOG.md (v1.1.7 section) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 00:15:48 +01:00
<?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']),
Release version 1.1.7 - Enhanced user experience features Added three new customer-facing features to improve product page interaction and tier pricing functionality. Features: - Optional text labels for tier pricing (similar to package labels) - Clickable tier pricing table rows to auto-populate quantity field - Add to Cart button auto-disables when quantity is 0 or less Enhanced User Experience: - Tier pricing rows now clickable with cursor pointer and hover animation - Clicking tier row sets quantity and smoothly scrolls to quantity field - Add to Cart button shows disabled state with reduced opacity - Tier labels display below quantity in italic gray text Technical Changes: - Added optional 'label' field to tier pricing admin meta box - Updated tier save logic to include label field (sanitized) - Enhanced tier pricing frontend template to display labels - Added click handler for tier pricing rows in frontend.js - Added updateAddToCartButton() function to manage button state - CSS: .wc-tpp-tier-label styling for tier labels - CSS: Clickable cursor and hover transform for tier rows - CSS: Disabled button styling (.single_add_to_cart_button:disabled) Updated Files: - templates/admin/tier-row.twig (added label field) - includes/class-wc-tpp-product-meta.php (save label, template update) - templates/frontend/tier-pricing-table.twig (display labels) - assets/js/frontend.js (tier row clicks, button disable logic) - assets/css/frontend.css (tier label style, clickable rows, disabled button) - wc-tier-and-package-prices.php (version 1.1.7) - composer.json (version 1.1.7) - CHANGELOG.md (v1.1.7 section) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 00:15:48 +01:00
'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);
}
}
new WC_TPP_Product_Meta();
}