Home > OS >  Add a select field on WooCommerce single product pages that allows an additional product to be added
Add a select field on WooCommerce single product pages that allows an additional product to be added

Time:04-06

I am looking to add a selection of products to some of our single product pages.

I have added a select field that is grabbing all of the products of a specific category and adding them as options.

Based on the users selection, I would like to add the selected product to the cart along with the main product. This only if the additional product is not yet in the cart.

Here is my code attempt:

function comp_bracket_selection( $selection ) {
    echo '<div><br></div>';
    global $product;
    $domain = 'woocommerce';

    $args = array(
        'category'      => 'compressor-brackets', 
        'limit'         => -1,
    );

    $product_array = wc_get_products( $args );
    foreach ($product_array as $comp_product) {
        $comp_id = $comp_product->get_id();
        echo 'Product id: ' . $comp_id . ' | ';
        $options[$comp_id] = $comp_product->get_name();
    }

    array_unshift($options, 'Choose an option');
    woocommerce_form_field('compressor-options', array(
        'id'            => 'compressor-selection',
        'type'          => 'select',
        'label'         => __('Choose Compressor & Bracket', $domain),
        'required'      => false,
        'options'       => $options,
        ),''
    );

    echo '<p>Number of Compressor & Bracket options: ' . sizeof( $product_array ) . '</p>';
}
add_action( 'woocommerce_before_add_to_cart_button', 'comp_bracket_selection' );

function custom_add_to_cart() {
    if (isset($_POST['compressor-options'])) {

        $product_id = $_POST['compressor-options'];
        $found = false;
        if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
            foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
                $_product = $values['data'];
                if ( $_product->id == $product_id )
                $found = true;
            }
            if ( ! $found )
            WC()->cart->add_to_cart( $product_id );
        } else {
            WC()->cart->add_to_cart( $product_id );
        }
    }
}
add_action( 'woocommerce_add_to_cart', 'custom_add_to_cart' );

But I have issues getting the selected products added to the cart. Any advice would be much appreciated.

CodePudding user response:

Some notes on your code attempt/question:

  • The mistake you make is using array_unshift() causing all numerical array keys will be modified to start counting from zero
  • You use $_POST['compressor-options'] and $_POST['compressor-selection'] while they should be equal
  • To check whether a product is already in cart you can use WC_Cart::find_product_in_cart()

So you get:

function action_woocommerce_before_add_to_cart_button() {
    global $product;

    $domain = 'woocommerce';

    $args = array(
        'category'      => 'compressor-bracket', 
        'limit'         => -1,
    );

    // Retrieving products
    $product_array = wc_get_products( $args );

    // NOT empty
    if ( ! empty( $product_array ) ) {
        foreach ( $product_array as $product ) {
            $product_id = $product->get_id();
            echo 'Product id: ' . $product_id . ' | ';
            $options[$product_id] = $product->get_name();
        }

        $options = array( 0 => __( 'Choose an option', $domain ) )   $options;

        // Add select field
        woocommerce_form_field( 'compressor-options', array(
            'id'            => 'compressor-selection',
            'type'          => 'select',
            'label'         => __( 'Choose Compressor & Bracket', $domain ),
            'required'      => false,
            'options'       => $options,
        ),'' );

        echo '<p>Number of Compressor & Bracket options: ' . sizeof( $product_array ) . '</p>';
    }
}
add_action( 'woocommerce_before_add_to_cart_button', 'action_woocommerce_before_add_to_cart_button' );

function filter_woocommerce_add_to_cart( $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data ) {
    if ( isset( $_POST['compressor-options'] ) ) {
        // Get product ID
        $the_product_id = sanitize_text_field( $_POST['compressor-options'] );

        // WC Cart
        if ( WC()->cart ) {
            // Get cart
            $cart = WC()->cart;
            
            // If cart is NOT empty
            if ( ! $cart->is_empty() ) {
                // Cart id
                $product_cart_id = $cart->generate_cart_id( $the_product_id );

                // Find product in cart
                $in_cart = $cart->find_product_in_cart( $product_cart_id );

                // NOT in cart
                if ( ! $in_cart ) {
                    $cart->add_to_cart( $the_product_id );
                }
            } else {
                $cart->add_to_cart( $the_product_id );
            }
        }
    }
}
add_action( 'woocommerce_add_to_cart', 'filter_woocommerce_add_to_cart', 10, 6 );

Note: if you want to exclude the current product from the select option list

Change:

$args = array(
    'category'      => 'compressor-bracket', 
    'limit'         => -1,
);

To:

$args = array(
    'category'      => 'compressor-bracket', 
    'limit'         => -1,
    'exclude'       => array( $product->get_id() ),
);
  • Related