Plugin Directory

Changeset 3250952


Ignore:
Timestamp:
03/05/2025 09:19:01 AM (5 days ago)
Author:
Rynald0s
Message:
  • WooCommerce Compatibility: Now tested up to WooCommerce 9.7.1.
  • Additional Shipping Methods: Added a new multiselect setting that lets admins choose extra shipping methods (pulled dynamically from shipping zones) to display alongside “Free Shipping” and “Local Pickup.”
  • Filter Priority Change: Increased the priority of shipping method filters from 10 to 99 to ensure compatibility with other plugins.
Location:
wc-hide-shipping-methods
Files:
42 added
3 edited

Legend:

Unmodified
Added
Removed
  • wc-hide-shipping-methods/trunk/hide-shipping-free-shipping.php

    r3222435 r3250952  
    33 * Plugin Name: WC Hide Shipping Methods
    44 * Plugin URI: https://wordpress.org/plugins/wc-hide-shipping-methods/
    5  * Documentation URI: https://wccare.co/
     5 * Documentation URI: https://orcawp.com
    66 * Description: Hides other shipping methods when "Free shipping" is available.
    77 * Author: Rynaldo Stoltz
    8  * Author URI: https://wccare.co/
    9  * Version: 1.8.3
     8 * Author URI: https://orcawp.com
     9 * Version: 1.8.4
    1010 * Text Domain: wc-hide-shipping-methods
    1111 * Domain Path: /languages
     
    1313 * License URI: http://www.gnu.org/licenses/gpl-3.0.html
    1414 * WC requires at least: 3.9.4
    15  * WC tested up to: 9.5.2
     15 * WC tested up to: 9.7.1
    1616 * Requires at least: 6.5
    1717 * Requires PHP: 7.4
     
    2020 */
    2121
    22 if (!defined('ABSPATH')) {
     22if ( ! defined( 'ABSPATH' ) ) {
    2323    exit; // Exit if accessed directly.
     24}
     25
     26/**
     27 * Custom function to output a multiselect field for WooCommerce settings.
     28 *
     29 * @param array $value Field arguments.
     30 */
     31if ( ! function_exists( 'woocommerce_admin_field_multiselect' ) ) {
     32    function woocommerce_admin_field_multiselect( $value ) {
     33        // Get the saved option.
     34        $option_value = get_option( $value['id'], $value['default'] );
     35        if ( ! is_array( $option_value ) ) {
     36            $option_value = explode( ',', $option_value );
     37        }
     38        ?>
     39        <tr valign="top">
     40            <th scope="row" class="titledesc">
     41                <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
     42            </th>
     43            <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ); ?>">
     44                <select multiple="multiple" style="<?php echo esc_attr( $value['css'] ); ?>" class="<?php echo esc_attr( $value['class'] ); ?>" id="<?php echo esc_attr( $value['id'] ); ?>" name="<?php echo esc_attr( $value['id'] ); ?>[]">
     45                    <?php
     46                    foreach ( $value['options'] as $key => $label ) {
     47                        $selected = in_array( $key, (array) $option_value, true ) ? 'selected="selected"' : '';
     48                        echo '<option value="' . esc_attr( $key ) . '" ' . $selected . '>' . esc_html( $label ) . '</option>';
     49                    }
     50                    ?>
     51                </select>
     52                <?php echo isset( $value['desc'] ) ? '<p class="description">' . wp_kses_post( $value['desc'] ) . '</p>' : ''; ?>
     53            </td>
     54        </tr>
     55        <?php
     56    }
    2457}
    2558
     
    2962 * Handles the hiding of shipping methods based on the settings in WooCommerce.
    3063 */
    31 class WC_Hide_Shipping_Methods
    32 {
     64class WC_Hide_Shipping_Methods {
     65
    3366    /**
    3467     * Constructor to initialize the class.
    3568     */
    36     public function __construct()
    37     {
     69    public function __construct() {
    3870        // Check if WooCommerce is active, if not, show an admin notice.
    39         add_action('admin_notices', [$this, 'check_woocommerce_active']);
     71        add_action( 'admin_notices', [ $this, 'check_woocommerce_active' ] );
    4072
    4173        // Add WooCommerce settings and declare compatibility.
    42         add_filter('woocommerce_get_settings_shipping', [$this, 'add_settings'], 10, 2);
    43         add_action('before_woocommerce_init', [$this, 'declare_woocommerce_compatibility']);
     74        add_filter( 'woocommerce_get_settings_shipping', [ $this, 'add_settings' ], 10, 2 );
     75        add_action( 'before_woocommerce_init', [ $this, 'declare_woocommerce_compatibility' ] );
    4476
    4577        // Register activation hook.
    46         register_activation_hook(__FILE__, [$this, 'update_default_option']);
     78        register_activation_hook( __FILE__, [ $this, 'update_default_option' ] );
    4779
    4880        // Add plugin action links.
    49         add_filter('plugin_action_links_' . plugin_basename(__FILE__), [$this, 'plugin_action_links']);
    50 
    51         // Apply filters for hiding shipping methods.
     81        add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), [ $this, 'plugin_action_links' ] );
     82
     83        // Apply filters for hiding shipping methods with a higher priority.
    5284        $this->apply_shipping_method_filters();
    5385    }
     
    5688     * Checks if WooCommerce is active and shows a warning if it is not.
    5789     */
    58     public function check_woocommerce_active()
    59     {
    60         if (!is_plugin_active('woocommerce/woocommerce.php')) {
     90    public function check_woocommerce_active() {
     91        if ( ! is_plugin_active( 'woocommerce/woocommerce.php' ) ) {
    6192            $class   = 'error';
    6293            $message = sprintf(
     
    6596                    'wc-hide-shipping-methods'
    6697                ),
    67                 esc_url('https://wordpress.org/plugins/woocommerce/')
     98                esc_url( 'https://wordpress.org/plugins/woocommerce/' )
    6899            );
    69             printf('<div class="%1$s"><p>%2$s</p></div>', esc_attr($class), wp_kses_post($message));
     100            printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( $class ), wp_kses_post( $message ) );
    70101        }
    71102    }
     
    77108     * @return array Updated WooCommerce shipping settings.
    78109     */
    79     public function add_settings($settings)
    80     {
    81         $settings[] = [
    82             'title' => __('Shipping Method Visibility', 'wc-hide-shipping-methods'),
     110    public function add_settings( $settings ) {
     111        $settings[] = [
     112            'title' => __( 'Shipping Method Visibility', 'wc-hide-shipping-methods' ),
    83113            'type'  => 'title',
    84114            'id'    => 'wc_hide_shipping',
     
    86116
    87117        $settings[] = [
    88             'title'    => __('Free Shipping: ', 'wc-hide-shipping-methods'),
     118            'title'    => __( 'Free Shipping: ', 'wc-hide-shipping-methods' ),
    89119            'desc'     => '',
    90120            'id'       => 'wc_hide_shipping_options',
     
    92122            'desc_tip' => true,
    93123            'options'  => [
    94                 'hide_all'          => __('Show "Free Shipping" only (if available). Hide all the other methods', 'wc-hide-shipping-methods'),
    95                 'hide_except_local' => __('Show "Free Shipping" and "Local Pickup" only (if available). Hide all the other methods.', 'wc-hide-shipping-methods'),
     124                'hide_all'          => __( 'Show "Free Shipping" only (if available). Hide all the other methods', 'wc-hide-shipping-methods' ),
     125                'hide_except_local' => __( 'Show "Free Shipping" and "Local Pickup" only (if available). Hide all the other methods.', 'wc-hide-shipping-methods' ),
    96126            ],
    97127        ];
     128
     129        // ------------------------------------------------------------------
     130        // NEW: Additional methods to display (Pulled from available shipping zones)
     131        // ------------------------------------------------------------------
     132        $settings[] = [
     133            'title'             => __( 'Additional methods to display alongside the above setting', 'wc-hide-shipping-methods' ),
     134            'desc'              => __( 'Select any additional shipping methods you want to display alongside free shipping (and local pickup, if applicable).', 'wc-hide-shipping-methods' ),
     135            'id'                => 'wc_hide_shipping_additional_methods',
     136            'type'              => 'multiselect', // Our custom multiselect field.
     137            'class'             => 'wc-enhanced-select',
     138            'css'               => 'width: 400px;',
     139            'options'           => $this->get_available_shipping_methods(),
     140            'default'           => [],
     141        ];
     142        // ------------------------------------------------------------------
    98143
    99144        $settings[] = [
     
    102147        ];
    103148
     149        // ------------------------------------------------------------------
     150        // NEW: Support & notice section
     151        // ------------------------------------------------------------------
     152        $settings[] = [
     153            'title' => __( 'Support & Other Plugins', 'wc-hide-shipping-methods' ),
     154            'type'  => 'title',
     155            'id'    => 'wc_hide_shipping_notice',
     156            'desc'  => '<div style="border: 1px solid #ddd; border-radius: 4px; background-color: #fff; padding: 20px; margin: 10px 0; box-shadow: 0 1px 3px rgba(0,0,0,0.1);">
     157                        <p style="font-size: 15px; margin: 0 0 15px;">For support with this plugin, please visit <a href="https://orcawp.com" target="_blank" style="color: #0073aa; text-decoration: none;">Orca</a>. You may also be interested in some of our other plugins:</p>
     158                                <strong><a href="https://orcawp.com/product/advanced-per-product-shipping-for-woocommerce/" target="_blank" style="color: #0073aa; text-decoration: none;">Advanced Per Product Shipping for WooCommerce</a></strong>: Add shipping fees for individual products or entire product categories, and even restrict it to specific WooCommerce shipping zones or target custom zip/postcodes.</br>
     159                                <strong><a href="https://orcawp.com/product/shipping-importer-and-exporter-for-woocommerce/" target="_blank" style="color: #0073aa; text-decoration: none;">Shipping Importer and Exporter for WooCommerce</a></strong>: Easily export and import your shipping zones, methods, locations, rates, and settings with just a few clicks.
     160                        </ul>
     161                    </div>',
     162        ];
     163        $settings[] = [
     164            'type' => 'sectionend',
     165            'id'   => 'wc_hide_shipping_notice',
     166        ];
     167
    104168        return $settings;
    105169    }
    106170
    107171    /**
     172     * Helper method to dynamically pull available shipping methods from WooCommerce shipping zones.
     173     *
     174     * @return array Available shipping methods with keys in the format "method_id:instance_id" (if applicable) and values as titles.
     175     */
     176    public function get_available_shipping_methods() {
     177        $available = [];
     178
     179        if ( ! class_exists( 'WC_Shipping_Zones' ) ) {
     180            return $available;
     181        }
     182
     183        // Get default zone (zone id 0) which covers methods not assigned to a specific zone.
     184        $default_zone    = new WC_Shipping_Zone( 0 );
     185        $default_methods = $default_zone->get_shipping_methods();
     186        foreach ( $default_methods as $method ) {
     187            $title = method_exists( $method, 'get_title' ) ? $method->get_title() : $method->get_method_title();
     188            $key   = $method->id;
     189            if ( isset( $method->instance_id ) && $method->instance_id ) {
     190                $key .= ':' . $method->instance_id;
     191            }
     192            $available[ $key ] = $title . ' (' . __( 'Default Zone', 'wc-hide-shipping-methods' ) . ')';
     193        }
     194
     195        // Get all configured zones.
     196        $zones = WC_Shipping_Zones::get_zones();
     197        if ( is_array( $zones ) && ! empty( $zones ) ) {
     198            foreach ( $zones as $zone_data ) {
     199                $zone         = new WC_Shipping_Zone( $zone_data['id'] );
     200                $zone_methods = $zone->get_shipping_methods();
     201                foreach ( $zone_methods as $method ) {
     202                    $title = method_exists( $method, 'get_title' ) ? $method->get_title() : $method->get_method_title();
     203                    $key   = $method->id;
     204                    if ( isset( $method->instance_id ) && $method->instance_id ) {
     205                        $key .= ':' . $method->instance_id;
     206                    }
     207                    $available[ $key ] = $title . ' (' . $zone->get_zone_name() . ')';
     208                }
     209            }
     210        }
     211
     212        return $available;
     213    }
     214
     215    /**
    108216     * Apply filters based on the selected shipping method option.
    109217     */
    110     private function apply_shipping_method_filters()
    111     {
    112         $option = get_option('wc_hide_shipping_options', 'hide_all'); // Default to 'hide_all' if option is not set.
    113 
    114         if ('hide_all' === $option) {
    115             add_filter('woocommerce_package_rates', [$this, 'hide_shipping_when_free_is_available'], 10, 2);
    116         } elseif ('hide_except_local' === $option) {
    117             add_filter('woocommerce_package_rates', [$this, 'hide_shipping_when_free_is_available_keep_local'], 10, 2);
     218    private function apply_shipping_method_filters() {
     219        $option = get_option( 'wc_hide_shipping_options', 'hide_all' ); // Default to 'hide_all' if option is not set.
     220
     221        // Use a higher priority (99) so that our filter runs later.
     222        if ( 'hide_all' === $option ) {
     223            add_filter( 'woocommerce_package_rates', [ $this, 'hide_shipping_when_free_is_available' ], 99, 2 );
     224        } elseif ( 'hide_except_local' === $option ) {
     225            add_filter( 'woocommerce_package_rates', [ $this, 'hide_shipping_when_free_is_available_keep_local' ], 99, 2 );
    118226        }
    119227    }
     
    125233     * @return array Filtered array of shipping rates.
    126234     */
    127     public function hide_shipping_when_free_is_available($rates)
    128     {
    129         $free = [];
    130         foreach ($rates as $rate_id => $rate) {
    131             if ('free_shipping' === $rate->method_id) {
    132                 $free[$rate_id] = $rate;
    133             }
    134         }
    135         return !empty($free) ? $free : $rates;
     235    public function hide_shipping_when_free_is_available( $rates ) {
     236        $free       = [];
     237        // Ensure the additional methods value is treated as an array.
     238        $additional = (array) get_option( 'wc_hide_shipping_additional_methods', [] );
     239
     240        foreach ( $rates as $rate_id => $rate ) {
     241            if ( 'free_shipping' === $rate->method_id ) {
     242                $free[ $rate_id ] = $rate;
     243            } elseif ( in_array( $rate->method_id . ( isset( $rate->instance_id ) && $rate->instance_id ? ':' . $rate->instance_id : '' ), $additional, true ) ) {
     244                $free[ $rate_id ] = $rate;
     245            }
     246        }
     247        return ! empty( $free ) ? $free : $rates;
    136248    }
    137249
     
    143255     * @return array Filtered array of shipping rates.
    144256     */
    145     public function hide_shipping_when_free_is_available_keep_local($rates, $package)
    146     {
    147         $new_rates = [];
    148         foreach ($rates as $rate_id => $rate) {
    149             if ('free_shipping' === $rate->method_id) {
    150                 $new_rates[$rate_id] = $rate;
    151             }
    152         }
    153 
    154         if (!empty($new_rates)) {
    155             foreach ($rates as $rate_id => $rate) {
    156                 // Check for both 'pickup_location' and 'local_pickup' for backward compatibility.
    157                 if ('pickup_location' === $rate->method_id || 'local_pickup' === $rate->method_id) {
    158                     $new_rates[$rate_id] = $rate;
     257    public function hide_shipping_when_free_is_available_keep_local( $rates, $package ) {
     258        $new_rates  = [];
     259        // Ensure the additional methods value is treated as an array.
     260        $additional = (array) get_option( 'wc_hide_shipping_additional_methods', [] );
     261
     262        foreach ( $rates as $rate_id => $rate ) {
     263            if ( 'free_shipping' === $rate->method_id ) {
     264                $new_rates[ $rate_id ] = $rate;
     265            }
     266        }
     267
     268        if ( ! empty( $new_rates ) ) {
     269            foreach ( $rates as $rate_id => $rate ) {
     270                if ( 'pickup_location' === $rate->method_id ||
     271                     'local_pickup' === $rate->method_id ||
     272                     in_array( $rate->method_id . ( isset( $rate->instance_id ) && $rate->instance_id ? ':' . $rate->instance_id : '' ), $additional, true )
     273                ) {
     274                    $new_rates[ $rate_id ] = $rate;
    159275                }
    160276            }
     
    168284     * Update the default option when the plugin is activated.
    169285     */
    170     public function update_default_option()
    171     {
    172         update_option('wc_hide_shipping_options', 'hide_all');
     286    public function update_default_option() {
     287        update_option( 'wc_hide_shipping_options', 'hide_all' );
    173288    }
    174289
     
    176291     * Declare plugin compatibility with WooCommerce HPOS and Cart & Checkout Blocks.
    177292     */
    178     public function declare_woocommerce_compatibility()
    179     {
    180         if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) {
    181             \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true);
    182             \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('cart_checkout_blocks', __FILE__, true);
     293    public function declare_woocommerce_compatibility() {
     294        if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
     295            \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
     296            \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', __FILE__, true );
    183297        }
    184298    }
     
    190304     * @return array Modified array of action links.
    191305     */
    192     public function plugin_action_links($links)
    193     {
    194         $settings_link = '<a href="' . esc_url(admin_url('admin.php?page=wc-settings&tab=shipping&section=options')) . '">' . __('Settings', 'wc-hide-shipping-methods') . '</a>';
    195         array_unshift($links, $settings_link); // Add the settings link to the beginning of the array.
     306    public function plugin_action_links( $links ) {
     307        $settings_link = '<a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=shipping&section=options' ) ) . '">' . __( 'Settings', 'wc-hide-shipping-methods' ) . '</a>';
     308        array_unshift( $links, $settings_link );
    196309        return $links;
    197310    }
  • wc-hide-shipping-methods/trunk/readme.txt

    r3222435 r3250952  
    55Requires at least: 6.5.0
    66Tested up to: 6.7.1
    7 Stable tag: 1.8.3
     7Stable tag: 1.8.4
    88WC requires at least: 3.9.4
    9 WC tested up to: 9.5.2
     9WC tested up to: 9.7.1
    1010License: GPLv3 or later License
    1111License URI: http://www.gnu.org/licenses/gpl-3.0.html
    1212
    13 This plugin hides all other shipping methods when "Free Shipping" is available, but you can keep "Local Pickup" alongside it.
     13This plugin automatically hides all other shipping methods when "Free Shipping" is available, while allowing you to retain "Local Pickup" and any additional shipping methods you select from your shipping zones.
    1414
    1515
     
    1919
    2020Key features:
    21 - Automatically hides all other shipping methods when "Free Shipping" is available.
    22 - Option to keep "Local Pickup" available with "Free Shipping".
    23 - Easy integration with WooCommerce settings.
    24 - Compatible with WooCommerce shipping zones.
    25 - Compatible with both classic and modern block-based checkout methods (i.e. Gutenberg & WooCommerce blocks).
     21- Automatic Shipping Method Hiding: Hides all other shipping options when “Free Shipping” is available for a cleaner checkout experience.
     22- Local Pickup Option: Choose to keep “Local Pickup” available alongside “Free Shipping.”
     23- Additional Shipping Methods: Administrators can select extra shipping methods (pulled from available WooCommerce shipping zones) to display in addition to the default options.
     24- Seamless WooCommerce Integration: Easily managed through WooCommerce settings.
     25- Shipping Zone Compatibility: Dynamically pulls shipping methods from your WooCommerce shipping zones.
     26- Block & Classic Compatibility: Fully supports both the modern block-based checkout (Gutenberg & WooCommerce blocks) and the classic WooCommerce checkout.
     27
     28Support & Other Plugins:
     29For support with WC Hide Shipping Methods, please visit our support page at [OrcaWP](https://orcawp.com). We also invite you to explore our other WooCommerce plugins:
     30
     31[Advanced Per Product Shipping for WooCommerce](https://orcawp.com/product/advanced-per-product-shipping-for-woocommerce/): Add shipping fees for individual products or categories, with zone-specific restrictions.
     32[Shipping Importer and Exporter for WooCommerce](https://orcawp.com/product/shipping-importer-and-exporter-for-woocommerce/): Easily manage your shipping zones, methods, locations, rates, and settings with a simple export/import process.
    2633
    2734== Installation ==
     
    3340   - Show "Free Shipping" only.
    3441   - Show "Free Shipping" and "Local Pickup" only.
     42   - Select any additional shipping methods you would like to show alongside that.
    35435. Save changes and enjoy the optimized checkout experience!
    3644
     
    4048A: Yes, the plugin is fully compatible with WooCommerce's shipping zones feature.
    4149
     50= Q: Is this plugin compatible with the new Local Pickup (Blocks edition)? =
     51A: Yes, the plugin is fully compatible with WooCommerce's new Local Pickup (Blocks edition).
     52
    4253= Q: Where can I go if I find an issue or want to recommend a feature? =
    43 A: You can submit issues or feature requests on the [Public GitHub Repository](https://github.com/riaanknoetze/wc-hide-shipping-methods-free/issues).
     54A: You can submit issues or feature requests on the [Orca WP Plugins](https://orcawp.com).
    4455
    4556== Screenshots ==
     
    4960
    5061== Changelog ==
     62
     63= 1.8.4 =
     64* WooCommerce Compatibility: Now tested up to WooCommerce 9.7.1.
     65* Additional Shipping Methods: Added a new multiselect setting that lets admins choose extra shipping methods (pulled dynamically from shipping zones) to display alongside “Free Shipping” and “Local Pickup.”
     66* Filter Priority Change: Increased the priority of shipping method filters from 10 to 99 to ensure compatibility with other plugins.
    5167
    5268= 1.8.3 =
Note: See TracChangeset for help on using the changeset viewer.