yoone-wc-product-bundles/templates/global/yoone-bundle-form.php

110 lines
5.3 KiB
PHP

<?php
/**
* Yoone Product Bundles - Mix and Match Product Selection Form
*
* This template part contains the full frontend interface for selecting bundle components,
* including the card-based layout, quantity inputs, and dynamically updated total count.
* It is hooked into `woocommerce_single_product_summary` to replace the standard add-to-cart form.
*
* @version 3.0.1
*/
defined('ABSPATH') || exit;
global $product;
// --- 数据准备逻辑 ---
$config = Yoone_Product_Bundles::get_bundle_config($product);
$allowed = $config['allowed_products'];
$min_qty = max(0, absint($config['min_qty']));
$cat_ids = $config['categories'];
$allowed_products = array();
foreach ($allowed as $pid) {
$p = wc_get_product($pid);
if ($p && $p->is_type('simple')) {
$allowed_products[$pid] = $p;
}
}
$groups = array();
if (!empty($cat_ids)) {
$others = array();
foreach ($allowed_products as $pid => $p) {
$terms = get_the_terms($pid, 'product_cat');
$matched = false;
if (is_array($terms)) {
foreach ($terms as $t) {
if (in_array($t->term_id, $cat_ids, true)) {
if (!isset($groups[$t->term_id])) {
$groups[$t->term_id] = array('term' => $t, 'items' => array());
}
$groups[$t->term_id]['items'][] = $p;
$matched = true;
}
}
}
if (!$matched) $others[] = $p;
}
if (!empty($others)) $groups[0] = array('term' => null, 'items' => $others);
} else {
$groups[0] = array('term' => null, 'items' => array_values($allowed_products));
}
// --- 数据准备逻辑结束 ---
?>
<div class="yoone-bundle-form-container">
<form class="cart yoone-bundle-form" action="<?php echo esc_url(apply_filters('woocommerce_add_to_cart_form_action', $product->get_permalink())); ?>" method="post" enctype="multipart/form-data">
<div class="yoone-bundle-meta">
<p class="yoone-bundle-min"><?php printf(esc_html__('Select at least %d items to build your bundle.', 'yoone-product-bundles'), $min_qty); ?></p>
<p class="yoone-bundle-selected"><?php esc_html_e('Currently selected:', 'yoone-product-bundles'); ?> <span class="yoone-bundle-selected-count">0</span></p>
<div class="yoone-bundle-actions">
<input type="hidden" name="add-to-cart" value="<?php echo esc_attr($product->get_id()); ?>" />
<button type="submit" class="single_add_to_cart_button button alt" disabled><?php esc_html_e('Add to Cart', 'yoone-product-bundles'); ?></button>
</div>
</div>
<?php if (empty($allowed_products)) : ?>
<p><?php esc_html_e('No products are available for this bundle. Please configure it in the backend.', 'yoone-product-bundles'); ?></p>
<?php else : ?>
<?php foreach ($groups as $gid => $group) : ?>
<div class="yoone-bundle-group">
<?php if (!empty($group['term'])) : ?>
<h3 class="yoone-bundle-group-title"><?php echo esc_html($group['term']->name); ?></h3>
<?php else : ?>
<h3 class="yoone-bundle-group-title"><?php esc_html_e('Available Products', 'yoone-product-bundles'); ?></h3>
<?php endif; ?>
<?php if (empty($group['items'])) : ?>
<p class="yoone-bundle-no-items"><?php esc_html_e('No products available in this group.', 'yoone-product-bundles'); ?></p>
<?php else : ?>
<div class="yoone-bundle-items-wrapper">
<?php foreach ($group['items'] as $item) : ?>
<?php
$pid = $item->get_id();
$thumbnail = $item->get_image('woocommerce_thumbnail');
?>
<div class="yoone-bundle-item-card">
<div class="item-image">
<a href="<?php echo esc_url(get_permalink($pid)); ?>" target="_blank">
<?php echo $thumbnail ? $thumbnail : wc_placeholder_img('woocommerce_thumbnail'); ?>
</a>
</div>
<h4 class="item-title">
<a href="<?php echo esc_url(get_permalink($pid)); ?>" target="_blank"><?php echo esc_html($item->get_name()); ?></a>
</h4>
<div class="item-price">
<?php echo wp_kses_post($item->get_price_html()); ?>
</div>
<div class="item-quantity">
<input type="number" min="0" step="1" class="yoone-bundle-qty" name="yoone_bundle_components[<?php echo esc_attr($pid); ?>]" value="0" placeholder="0" />
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<?php endforeach; ?>
<?php endif; ?>
</form>
</div>