const META_MIN_QTY = '_yoone_bundle_min_quantity'; // int const META_CATEGORIES = '_yoone_bundle_categories'; // array 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, ); } }