110 lines
5.3 KiB
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>
|