JezK
Edit File: free-delivery-manager.php
<?php /** * Plugin Name: Single Product Free Delivery Manager * Description: Offer free delivery for specific products. Hides all other shipping methods when free delivery is active. All code is contained in this single file. * Version: 1.1 * Author: Gemini */ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly // 1. Create Admin Menu add_action('admin_menu', 'spfd_add_admin_menu'); function spfd_add_admin_menu() { add_submenu_page( 'woocommerce', // Placed under the main WooCommerce menu 'Free Delivery Products', 'Free Delivery', 'manage_woocommerce', 'spfd-free-delivery', 'spfd_settings_page' ); } // 2. Enqueue WooCommerce AJAX Search Scripts (For auto-search) add_action('admin_enqueue_scripts', 'spfd_enqueue_admin_scripts'); function spfd_enqueue_admin_scripts($hook) { if ($hook !== 'woocommerce_page_spfd-free-delivery') return; wp_enqueue_script('wc-enhanced-select'); wp_enqueue_style('woocommerce_admin_styles'); } // 3. Admin Page Layout and Save Logic function spfd_settings_page() { // Save data when the form is submitted if (isset($_POST['spfd_save'])) { $products = isset($_POST['spfd_products']) ? array_map('intval', $_POST['spfd_products']) : array(); update_option('spfd_free_products', $products); echo '<div class="notice notice-success is-dismissible"><p>Settings saved successfully!</p></div>'; } // Fetch previously saved products $selected_products = get_option('spfd_free_products', array()); ?> <div class="wrap"> <h1>Free Delivery Management</h1> <p>Search and select the products that will be eligible for free delivery.</p> <form method="post"> <table class="form-table"> <tr> <th><label for="spfd_products">Search & Select Products:</label></th> <td> <select class="wc-product-search" multiple="multiple" style="width: 50%;" id="spfd_products" name="spfd_products[]" data-placeholder="Type product name..." data-action="woocommerce_json_search_products_and_variations"> <?php foreach ($selected_products as $product_id) { $product = wc_get_product($product_id); if (is_object($product)) { echo '<option value="' . esc_attr($product_id) . '" selected="selected">' . wp_kses_post($product->get_formatted_name()) . '</option>'; } } ?> </select> <p class="description">Type letter by letter to auto-search products. You can select multiple products.</p> </td> </tr> </table> <?php submit_button('Save Settings', 'primary', 'spfd_save'); ?> </form> </div> <?php } // 4. Control Shipping Rates on Checkout (Logic for hiding other methods) add_filter('woocommerce_package_rates', 'spfd_modify_shipping_rates', 10, 2); function spfd_modify_shipping_rates($rates, $package) { $free_products = get_option('spfd_free_products', array()); // If no products are set for free delivery, continue with regular shipping if (empty($free_products) || empty($rates)) return $rates; $all_free = true; // Check items currently in the cart foreach ($package['contents'] as $cart_item) { $product_id = $cart_item['product_id']; // For variable products, we check the parent product ID if ( $cart_item['variation_id'] > 0 ) { $product_id = $cart_item['product_id']; } // If the cart contains a product NOT in our free delivery list if (!in_array($product_id, $free_products)) { $all_free = false; break; // One normal product is enough to disable free delivery } } // If ALL products in the cart are eligible for free delivery if ($all_free) { $single_free_rate = array(); // Create a new empty array for shipping rates foreach ($rates as $rate_key => $rate) { // Take the very first available shipping method and convert it to Free Delivery $rates[$rate_key]->cost = 0; $rates[$rate_key]->taxes = array(); $rates[$rate_key]->label = 'Free Delivery'; // Assign only this modified rate to our new array $single_free_rate[$rate_key] = $rates[$rate_key]; break; // Stop the loop immediately so no other methods are added } // Return only the single free delivery option, effectively hiding the rest return $single_free_rate; } // If there are mixed products, return the default paid rates. return $rates; } ?>