Home > Back-end >  Add WooCommerce product to cart by SKU
Add WooCommerce product to cart by SKU

Time:06-01

Maybe someone could give me a hand resolving this challenge.

I was looking for a solution which would allow me to add products to cart by SKU's instead of WooCommerce generated ID's as I would like to use the same products across different CMS systems.

I have stumbled upon the below code, but it seems not to be compatible anymore? Any advice?

<?php
/**
 * Plugin Name: WooCommerce: Add Product to Cart by SKU
 * Plugin URI: http://remicorson.com
 * Description: Just a demo!
 * Version: 1.0
 * Author: Remi Corson
 * Author URI: http://remicorson.com/
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}



/**
 * WC Product Add to Cart by SKU class
 */
class WC_Add_to_Cart_by_SKU {

    /**
     * Constructor
     */
    public function __construct() {

        define( 'WC_ADD_TO_CART_BY_SKU_VERSION', '1.0' );
        define( 'WC_ADD_TO_CART_BY_SKU_PATH', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
        define( 'WC_ADD_TO_CART_BY_SKU_PLUGIN_URL', untrailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) );
    }
    
    /**
     * get_product_id_by_product_sku()
     * 
     * Return product ID from product SKU
     */
    public function get_product_id_by_product_sku( $add_to_cart ) {
    
        global $wpdb;
              
        $product_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s' LIMIT 1", $add_to_cart ) );
              
        if ( $product_id ) return $product_id;
                
        return $add_to_cart;
    
    }
    
}

add_filter( 'woocommerce_add_to_cart_product_id', array( new WC_Add_to_Cart_by_SKU(), 'get_product_id_by_product_sku' ) );

Source: https://gist.github.com/corsonr/c02b46bd34a8471327bbf3adee6507c8

CodePudding user response:

There is no need to use a custom SQL query, as you can use the wc_get_product_id_by_sku() WooCommerce function.

Using this function is much more lighter and effective but also takes into account products that are not in trash. Something your current code doesn't do.

So, this snippet will suffice:

function filter_woocommerce_add_to_cart_product_id( $product_id ) {
    // Retrieves the post type of the current post or of a given post
    if ( get_post_type( $product_id ) === 'product' ) {
        return $product_id;
    } else {
        $sku = $product_id;
    }

    // Get product ID by SKU
    $product_id = wc_get_product_id_by_sku( $sku );

    return $product_id;
}
add_filter( 'woocommerce_add_to_cart_product_id', 'filter_woocommerce_add_to_cart_product_id', 10, 1 );

Note: SKU is assumed to be a numerical value


As you can read in the note, the above answer will only work for numerical values, to make this work for all SKU values, ​​you can use as custom query string = /?add-to-cart-sku=THE-SKU

So you get:

function action_wp_loaded( $url = false ) {
    // Make sure WC is installed and add-to-cart-sku query arg exists
    if ( ! class_exists( 'WC_Form_Handler' ) || ! isset( $_REQUEST['add-to-cart-sku'] ) || ! is_string( $_REQUEST['add-to-cart-sku'] ) ) {
        return;
    }
     
    // Remove WooCommerce's hook, as it's useless
    remove_action( 'wp_loaded', array( 'WC_Form_Handler', 'add_to_cart_action' ), 20 );

    wc_nocache_headers();

    $product_id        = wc_get_product_id_by_sku( wp_unslash( $_REQUEST['add-to-cart-sku'] ) );
    $was_added_to_cart = false;
    $adding_to_cart    = wc_get_product( $product_id );

    if ( ! $adding_to_cart ) {
        return;
    }

    $add_to_cart_handler = apply_filters( 'woocommerce_add_to_cart_handler', $adding_to_cart->get_type(), $adding_to_cart );

    if ( 'variable' === $add_to_cart_handler || 'variation' === $add_to_cart_handler ) {
        $was_added_to_cart = woo_hack_invoke_private_method( 'WC_Form_Handler', 'add_to_cart_handler_variable', $product_id );
    } elseif ( 'grouped' === $add_to_cart_handler ) {
        $was_added_to_cart = woo_hack_invoke_private_method( 'WC_Form_Handler', 'add_to_cart_handler_grouped', $product_id );
    } elseif ( has_action( 'woocommerce_add_to_cart_handler_' . $add_to_cart_handler ) ) {
        do_action( 'woocommerce_add_to_cart_handler_' . $add_to_cart_handler, $url ); // Custom handler.
    } else {
        $was_added_to_cart = woo_hack_invoke_private_method( 'WC_Form_Handler', 'add_to_cart_handler_simple', $product_id );
    }

    // If we added the product to the cart we can now optionally do a redirect.
    if ( $was_added_to_cart && 0 === wc_notice_count( 'error' ) ) {
        $url = apply_filters( 'woocommerce_add_to_cart_redirect', $url, $adding_to_cart );

        if ( $url ) {
            wp_safe_redirect( $url );
            exit;
        } elseif ( 'yes' === get_option( 'woocommerce_cart_redirect_after_add' ) ) {
            wp_safe_redirect( wc_get_cart_url() );
            exit;
        }
    }
}
// Fire before the WC_Form_Handler::add_to_cart_action callback.
add_action( 'wp_loaded', 'action_wp_loaded', 15 );

/**
* Invoke class private method
*
* @since 0.1.0
*
* @param string $class_name
* @param string $methodName
*
* @return mixed
*/
function woo_hack_invoke_private_method( $class_name, $methodName ) {
    if ( version_compare( phpversion(), '5.3', '<' ) ) {
        throw new Exception( 'PHP version does not support ReflectionClass::setAccessible()' );
    }

    $args = func_get_args();
    unset( $args[0], $args[1] );
    $reflection = new ReflectionClass( $class_name );
    $method = $reflection->getMethod( $methodName );
    $method->setAccessible( true );
    $args = array_merge( array( $reflection ), $args );
    return call_user_func_array( array( $method, 'invoke' ), $args );
}

Based on: Allow adding multiple products to the cart via the add-to-cart query string & /includes/class-wc-form-handler.php

CodePudding user response:

please try this one, i have include the filter call inside __constructor:

<?php
/**
 * Plugin Name: WooCommerce: Add Product to Cart by SKU
 * Plugin URI: http://remicorson.com
 * Description: Just a demo!
 * Version: 1.0
 * Author: Remi Corson
 * Author URI: http://remicorson.com/
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}


/**
 * WC Product Add to Cart by SKU class
 */
class WC_Add_to_Cart_by_SKU {

    /**
     * Constructor
     */
    public function __construct() {

        define( 'WC_ADD_TO_CART_BY_SKU_VERSION', '1.0' );
        define( 'WC_ADD_TO_CART_BY_SKU_PATH', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
        define( 'WC_ADD_TO_CART_BY_SKU_PLUGIN_URL', untrailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) );
        
        add_filter( 'woocommerce_add_to_cart_product_id', array(
            $this,
            'get_product_id_by_product_sku'
        ) );
    }

    /**
     * get_product_id_by_product_sku()
     *
     * Return product ID from product SKU
     */
    public function get_product_id_by_product_sku( $add_to_cart ) {

        global $wpdb;

        $product_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s' LIMIT 1", $add_to_cart ) );

        if ( $product_id ) {
            return $product_id;
        }

        return $add_to_cart;

    }

}

new WC_Add_to_Cart_by_SKU();

  • Related