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

147 lines
6.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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'];
$select_mode = isset($config['select_mode']) ? $config['select_mode'] : 'include';
$min_qty = max(0, absint($config['min_qty']));
// 读取按 taxonomy 分组的配置(支持 product_cat / product_tag
$group_taxonomy = isset($config['group_taxonomy']) ? $config['group_taxonomy'] : 'product_cat';
$term_ids = isset($config['group_terms']) ? (array) $config['group_terms'] : array();
$allowed_products = array();
foreach ($allowed as $pid) {
$p = wc_get_product($pid);
if ($p && $p->is_type('simple')) {
$allowed_products[$pid] = $p;
}
}
// 兜底:如果为 exclude/all 模式,但由于缓存或其他原因导致 allowed_products 为空,则直接读取所有 simple 产品
if (empty($allowed_products) && in_array($select_mode, array('exclude','all'), true)) {
$all_ids = wc_get_products(array(
'type' => array('simple'),
'status' => array('publish'),
'limit' => -1,
'return' => 'ids',
));
if (is_array($all_ids)) {
foreach ($all_ids as $pid) {
$p = wc_get_product($pid);
if ($p && $p->is_type('simple')) {
$allowed_products[$pid] = $p;
}
}
}
}
$groups = array();
if (!empty($term_ids)) {
$is_grouped = true;
$others = array();
foreach ($allowed_products as $pid => $p) {
$terms = get_the_terms($pid, $group_taxonomy);
$matched = false;
if (is_array($terms)) {
foreach ($terms as $t) {
if (in_array($t->term_id, $term_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 {
$is_grouped = false;
$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
// 兼容其它插件(如订阅插件)在标准钩位渲染附加选项
// 这些钩子通常位于默认的 add-to-cart 模板中,这里手动插入以实现联动。
do_action('woocommerce_before_add_to_cart_button');
?>
<?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 echo $is_grouped
? esc_html__('Others', 'yoone-product-bundles')
: esc_html__('All 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; ?>
<?php
// 按照默认模板的结构,在按钮之后触发 after 钩子
do_action('woocommerce_after_add_to_cart_button');
?>
</form>
</div>