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

80 lines
3.1 KiB
PHP

<?php
/**
* Core: Registers the product type, constants, and utility methods.
*/
defined('ABSPATH') || exit;
class Yoone_Product_Bundles {
const TYPE = 'yoone_bundle';
// Post meta keys for configuration
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 "Mix and Match" to the "Product Type" dropdown in the admin.
add_filter('product_type_selector', array($this, 'register_product_type_in_selector'));
// Map the type to our class name, so WooCommerce instantiates the correct product object.
add_filter('woocommerce_product_class', array($this, 'map_product_class'), 10, 2);
}
/**
* Add "Mix and Match" to the "Product Type" dropdown in the admin.
*/
public function register_product_type_in_selector($types) {
$types[self::TYPE] = __('Mix and Match (Yoone Bundle)', 'yoone-product-bundles');
return $types;
}
/**
* Map the type to our class name, so WooCommerce instantiates the correct product object.
*/
public function map_product_class($classname, $product_type) {
if ($product_type === self::TYPE) {
$classname = 'WC_Product_Yoone_Bundle';
}
return $classname;
}
/**
* Read and normalize the bundle configuration.
* @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);
// Keep only simple products (to avoid issues if variations or other types were selected in the backend)
$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,
);
}
}