80 lines
3.1 KiB
PHP
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,
|
|
);
|
|
}
|
|
} |