Mauro Beretta
Mauro Beretta

Reputation: 35

Add variation setting fields to specific variable products in Woocommerce

I added the custom fields to product variations (following this guide. It's work fine but it add the custom fields to all products. I would like to add the custom fields only to specific products and its variations. For example: if product id is equal to '1234' then WP add custom fields to its variations.

I try to work on this in function.php:

global $post;      
$product_id = $post->ID; 
$product_array = array( 1234, 9999 );
if ( in_array( $product_id, $product_array )) {
    // add custom field
}

...but it works only on the product and not on its variations.

It's possibile? Thank you very much!

Upvotes: 2

Views: 410

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 254373

To target specific variable products (and all its variations), you can directly get the parent variable product ID from the $variations 3rd function argument (the WP_Post object of the current variation), using post_parent field.

So you will use instead:

$targeted_ids = array( 1234, 9999 ); // Targeted variable products IDs

if ( in_array( $variation->post_parent, $targeted_ids )) {
    // add a custom setting field
}

Here is a complete code example with an input text field:

// Add custom field(s) to product variations from specific variable products
add_action( 'woocommerce_product_after_variable_attributes', 'add_variation_setting_fields', 10, 3 );
function add_variation_setting_fields( $loop, $variation_data, $variation ) {
    $targeted_ids = array( 1234, 9999 ); // Targeted variable product Ids

    if ( ! in_array( $variation->post_parent, $targeted_ids ) ) return;

    $field_key1 = 'my_custom_field';
    
    woocommerce_wp_text_input( array(
        'id'            => $field_key1.'['.$loop.']',
        'label'         => __('Text field Name', 'woocommerce'),
        'wrapper_class' => 'form-row',
        'placeholder'   => __('Text field placeholder', 'woocommerce'),
        'description'   => __('Text field description', 'woocommerce'),
        'desc_tip'      => true,
        'value'         => get_post_meta($variation->ID, $field_key1, true)
    ) );
}

// Save the custom field from product variations
add_action('woocommerce_admin_process_variation_object', 'save_variation_setting_fields', 10, 2 );
function save_variation_setting_fields($variation, $i) {
    $field_key1 = 'my_custom_field';

    if ( isset($_POST[$field_key1][$i]) ) {
        $variation->update_meta_data($field_key1, sanitize_text_field($_POST[$field_key1][$i]));
    }
}

Code goes in functions.php file of your child theme (or in a plugin). Tested and works.


For multiple input text fields:

You can use the following optimized code version (where the fields settings are in a reusable custom function):

// Fields settings
function custom_fields_settings() {
    return array(
        'my_custom_field1' => array(
            'label'       => __('Text field Name 1', 'woocommerce'),
            'placeholder' => __('Text field placeholder 1', 'woocommerce'),
            'description' => __('Text field description 1', 'woocommerce'),
        ),
        'my_custom_field2' => array(
            'label'       => __('Text field Name 2', 'woocommerce'),
            'placeholder' => __('Text field placeholder 2', 'woocommerce'),
            'description' => __('Text field description 2', 'woocommerce'),
        ),
        'my_custom_field3' => array(
            'label'       => __('Text field Name 3', 'woocommerce'),
            'placeholder' => __('Text field placeholder 3', 'woocommerce'),
            'description' => __('Text field description 3', 'woocommerce'),
        ),
    );
}


// Add custom field(s) to product variations from specific variable products
add_action( 'woocommerce_product_after_variable_attributes', 'add_variation_setting_fields', 10, 3 );
function add_variation_setting_fields( $loop, $variation_data, $variation ) {
    $targeted_ids = array( 1234, 9999 ); // Targeted variable product Ids

    if ( ! in_array( $variation->post_parent, $targeted_ids ) ) return;

    foreach(  custom_fields_settings() as $field_key => $values ) {
        $args = array(
            'id'            => $field_key.'['.$loop.']',
            'wrapper_class' => 'form-row',
            'desc_tip'      => true,
            'value'         => get_post_meta($variation->ID, $field_key, true)
        );
        woocommerce_wp_text_input( array_merge( $args, $values) );
    }
}

// Save the custom field from product variations
add_action('woocommerce_admin_process_variation_object', 'save_variation_setting_fields', 10, 2 );
function save_variation_setting_fields($variation, $i) {
    foreach(  custom_fields_settings() as $field_key => $values ) {
        if ( isset($_POST[$field_key][$i]) ) {
            $variation->update_meta_data($field_key, sanitize_text_field($_POST[$field_key][$i]));
        }
    }
}

Then to add this custom-fields to the variable product form data, use:

// Add variations custom fields to the variable product form data
add_action( 'woocommerce_available_variation', 'add_variations_custom_fields_to_variable_product_form', 10, 3 );
function add_variations_custom_fields_to_variable_product_form( $data, $product, $variation ) {
    $targeted_ids = array( 1234, 9999 ); // Targeted variable product Ids

    if ( ! in_array( $product->get_id(), $targeted_ids ) ) return $data;

    foreach(  custom_fields_settings() as $field_key => $values ) {
        if ( $value = $variation->get_meta($field_key)) {
            $data[$field_key] = $value;
        }
    }
    return  $data;
}

Upvotes: 1

Related Questions