Files
wc-composable-product/includes/Product_Selector.php

78 lines
2.7 KiB
PHP
Raw Normal View History

<?php
/**
* Product Selector
*
* @package WC_Composable_Product
*/
namespace WC_Composable_Product;
defined('ABSPATH') || exit;
/**
* Product Selector Class
*
* Handles rendering the product selection interface
*/
class Product_Selector {
/**
* Render product selector
*
* @param Product_Type $product Composable product
*/
public static function render($product) {
if (!$product || $product->get_type() !== 'composable') {
return;
}
$available_products = $product->get_available_products();
$selection_limit = $product->get_selection_limit();
$pricing_mode = $product->get_pricing_mode();
$show_images = get_option('wc_composable_show_images', 'yes') === 'yes';
$show_prices = get_option('wc_composable_show_prices', 'yes') === 'yes';
$show_total = get_option('wc_composable_show_total', 'yes') === 'yes';
// Get stock manager for stock information
$stock_manager = new Stock_Manager();
// Prepare product data for template
$products_data = [];
foreach ($available_products as $available_product) {
$stock_info = $stock_manager->get_product_stock_info($available_product->get_id());
$products_data[] = [
'id' => $available_product->get_id(),
'name' => $available_product->get_name(),
'price' => $available_product->get_price(),
'price_html' => $available_product->get_price_html(),
'image_url' => wp_get_attachment_image_url($available_product->get_image_id(), 'thumbnail'),
'permalink' => $available_product->get_permalink(),
'stock_status' => $stock_info['stock_status'],
'in_stock' => $stock_info['in_stock'],
'stock_quantity' => $stock_info['stock_quantity'],
'managing_stock' => $stock_info['managing_stock'],
'backorders_allowed' => $stock_info['backorders_allowed'],
];
}
$context = [
'product_id' => $product->get_id(),
'products' => $products_data,
'selection_limit' => $selection_limit,
'pricing_mode' => $pricing_mode,
'show_images' => $show_images,
'show_prices' => $show_prices,
'show_total' => $show_total,
'fixed_price' => $product->get_price(),
Fix critical UI bugs in admin and frontend Fixes three critical bugs reported in CLAUDE.md: 1. Admin rendering bug - Fixed CSS to prevent both General and Composable Options tabs from showing simultaneously on initial page load - Enhanced CSS specificity with !important flags - Added body.product-type-composable selectors for proper visibility control - Hides Composable Options tab by default, shows only when composable type selected 2. Frontend product selector not appearing - Fixed WooCommerce integration - Added hide_default_add_to_cart() method to Cart_Handler - Hooks woocommerce_is_purchasable filter to return false for composable products - This hides WooCommerce's default add-to-cart button - Allows our custom product selector to be the only interface 3. Localized price formatting - Implemented proper WooCommerce price formatting - Added wc_price Twig function in Plugin.php - Updated Product_Selector to pass formatted price HTML to template - Added price_format data to JavaScript localization - Implemented formatPrice() method in frontend.js - Supports all WooCommerce price formats (currency position, decimals, separators) - Template now uses {{ fixed_price_html|raw }} and {{ zero_price_html|raw }} - JavaScript dynamically formats prices using locale-specific settings Technical improvements: - Cart_Handler.php: +14 lines (hide_default_add_to_cart method) - Plugin.php: +7 lines (wc_price function, price format localization) - Product_Selector.php: +2 lines (formatted price HTML context) - templates/product-selector.twig: Modified to use formatted price HTML - assets/css/admin.css: +24 lines (enhanced tab visibility control) - assets/js/frontend.js: +28 lines (formatPrice method with WooCommerce format support) All PHP files pass lint checks. Frontend now properly displays localized prices with correct currency symbols, decimal separators, and thousand separators for all WooCommerce-supported locales (CHF for Switzerland, € for Europe, etc.). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 22:08:08 +01:00
'fixed_price_html' => wc_price($product->get_price()),
'zero_price_html' => wc_price(0),
'currency_symbol' => get_woocommerce_currency_symbol(),
];
// Render template
$plugin = Plugin::instance();
echo $plugin->render_template('product-selector.twig', $context);
}
}