yoone-wc-product-bundles/includes/class-yoone-product-bundles...

80 lines
3.0 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
/**
* 核心:注册产品类型、常量、工具方法。
*/
defined('ABSPATH') || exit;
class Yoone_Product_Bundles {
const TYPE = 'yoone_bundle';
// 配置的 postmeta 键名
const META_ALLOWED_PRODUCTS = '_yoone_bundle_allowed_products'; // array<int>
const META_MIN_QTY = '_yoone_bundle_min_quantity'; // int
const META_CATEGORIES = '_yoone_bundle_categories'; // array<int> product_cat term_ids
protected static $instance = null;
public static function instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
// 将产品类型加入选择器
add_filter('product_type_selector', array($this, 'register_product_type_in_selector'));
// 将类型映射到我们的 WC_Product 派生类
add_filter('woocommerce_product_class', array($this, 'map_product_class'), 10, 2);
}
/**
* 在后台“产品类型”下拉中添加“混装产品”。
*/
public function register_product_type_in_selector($types) {
$types[self::TYPE] = __('混装产品 (Yoone Bundle)', 'yoone-product-bundles');
return $types;
}
/**
* 将类型映射到类名WooCommerce 会实例化对应产品对象。
*/
public function map_product_class($classname, $product_type) {
if ($product_type === self::TYPE) {
$classname = 'WC_Product_Yoone_Bundle';
}
return $classname;
}
/**
* 读取并规范化 bundle 配置。
* @param int|WC_Product $product
* @return array{allowed_products:int[],min_qty:int,categories:int[]}
*/
public static function get_bundle_config($product) {
$product = is_numeric($product) ? wc_get_product($product) : $product;
if (! $product) return array('allowed_products' => array(), 'min_qty' => 0, 'categories' => array());
$pid = $product->get_id();
$allowed = get_post_meta($pid, self::META_ALLOWED_PRODUCTS, true);
$min = absint(get_post_meta($pid, self::META_MIN_QTY, true));
$cats = get_post_meta($pid, self::META_CATEGORIES, true);
// 仅保留 simple 产品(避免后台选择了变体或其他类型导致前端不显示)
$allowed = is_array($allowed) ? array_values(array_map('absint', $allowed)) : array();
if (! empty($allowed)) {
$simple_only = array();
foreach ($allowed as $aid) {
$p = wc_get_product($aid);
if ($p && $p->is_type('simple')) {
$simple_only[] = $aid;
}
}
$allowed = $simple_only;
}
$cats = is_array($cats) ? array_values(array_map('absint', $cats)) : array();
return array(
'allowed_products' => $allowed,
'min_qty' => max(0, $min),
'categories' => $cats,
);
}
}