Samuel Clayton
Samuel Clayton

Reputation: 35

Restrict a custom plugin functionality to a specific Woocommerce product or category

First of all, I understand there are similar topics on stackoverflow, but nothing that I have tried that should work, is working for me.

I have created a plugin to take text input from the user on all product pages. I need this extra functionality to only run on certain products, or certain products within a category.

Here is the functionality.

function kia_custom_option(){
$value = isset( $_POST['_custom_option'] ) ? sanitize_text_field( $_POST['_custom_option'] ) : '';
printf( '<label>%s</label><input name="_custom_option" value="%s" />', __( 'Custom Text: ', 'kia-plugin-textdomain' ), esc_attr( $value ) );
}
add_action( 'woocommerce_before_add_to_cart_button', 'kia_custom_option', 9 );

function kia_add_to_cart_validation($passed, $product_id, $qty){

if( isset( $_POST['_custom_option'] ) && sanitize_text_field( $_POST['_custom_option'] ) == '' ){
    $product = wc_get_product( $product_id );
    wc_add_notice( sprintf( __( '%s cannot be added to the cart until you enter your custom text.', 'kia-plugin-textdomain' ), $product->get_title() ), 'error' );
    return false;
}

return $passed;

}
add_filter( 'woocommerce_add_to_cart_validation', 'kia_add_to_cart_validation', 10, 3 );

function kia_add_cart_item_data( $cart_item, $product_id ){

if( isset( $_POST['_custom_option'] ) ) {
    $cart_item['custom_option'] = sanitize_text_field( $_POST['_custom_option'] );
}

return $cart_item;

}
add_filter( 'woocommerce_add_cart_item_data', 'kia_add_cart_item_data', 10, 2 );

function kia_get_cart_item_from_session( $cart_item, $values ) {

if ( isset( $values['custom_option'] ) ){
    $cart_item['custom_option'] = $values['custom_option'];
}

return $cart_item;

}
add_filter( 'woocommerce_get_cart_item_from_session', 'kia_get_cart_item_from_session', 20, 2 );

function kia_add_order_item_meta( $item_id, $values ) {

if ( ! empty( $values['custom_option'] ) ) {
    woocommerce_add_order_item_meta( $item_id, 'custom_option', $values['custom_option'] );           
}
}
add_action( 'woocommerce_add_order_item_meta', 'kia_add_order_item_meta', 10, 2 );

function kia_get_item_data( $other_data, $cart_item ) {

if ( isset( $cart_item['custom_option'] ) ){

    $other_data[] = array(
        'name' => __( 'Origin Email', 'kia-plugin-textdomain' ),
        'value' => sanitize_text_field( $cart_item['custom_option'] )
    );

}

return $other_data;

}
add_filter( 'woocommerce_get_item_data', 'kia_get_item_data', 10, 2 );

I am trying to only display the text box on certain products or categories. I have a product with the ID of 680.

I tried this at the top of my plugin.

if (is_single( '680' )) {
//All the above code here.
}

But that didn't work. I also tried by category, and had no luck with that either. Can someone explain to me what I am doing wrong or how I can apply these functions to only certain products?

Edit --- I came to the solution of:

function kia_custom_option(){
global $product;

$product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id;

if($product_id == 680 || $product_id == 687){
    $value = isset( $_POST['_custom_option'] ) ? sanitize_text_field( $_POST['_custom_option'] ) : '';
    printf( '<label>%s</label><input name="_custom_option" value="%s" />', __( 'Custom Text: ', 'kia-plugin-textdomain' ), esc_attr( $value ) );
}
}
add_action( 'woocommerce_before_add_to_cart_button', 'kia_custom_option', 9 );

Upvotes: 1

Views: 285

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 254428

Update (It seems that you are using a version of WooCommerce before version 3)

For product categories you can use has_term() Wordpress conditional function with the corresponding 'product_cat' custom taxonomy used by WooCommerce, just in your first hooked function, where you will define the allowed product category (or product categories) this way:

function kia_custom_option(){
    global $product;

    // HERE set your allowed product categories (can be IDs, slugs or names)
    $product_categories = array( 't-shirts', 'socks' );

    // Added WooCommerce retro compatibility
    $product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id;

    if( has_term( $product_categories, 'product_cat', $product_id ) ){

        $value = isset( $_POST['_custom_option'] ) ? sanitize_text_field( $_POST['_custom_option'] ) : '';
        printf( '<label>%s</label><input name="_custom_option" value="%s" />', __( 'Custom Text: ', 'kia-plugin-textdomain' ), esc_attr( $value ) );
    }
}
add_action( 'woocommerce_before_add_to_cart_button', 'kia_custom_option', 9 );

Code goes in function.php file of your active child theme (or active theme).

Tested and works (for all WC versions since 2.4). No need of anything else.


For defined product Ids the code will be:

function kia_custom_option(){
    global $product;

    // HERE set your allowed product IDs in the array
    $product_ids = array( 680, 687 );

    // Added WooCommerce retro compatibility
    $product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id;

    if( in_array( $product_id, $product_ids ) ){

        $value = isset( $_POST['_custom_option'] ) ? sanitize_text_field( $_POST['_custom_option'] ) : '';
        printf( '<label>%s</label><input name="_custom_option" value="%s" />', __( 'Custom Text: ', 'kia-plugin-textdomain' ), esc_attr( $value ) );
    }
}
add_action( 'woocommerce_before_add_to_cart_button', 'kia_custom_option', 9 );

Code goes in function.php file of your active child theme (or active theme).

Tested and works (for all WC versions since 2.4).

Upvotes: 1

Related Questions