Support

Account

Home Forums Backend Issues (wp-admin) Custom fields on woocommerce product variations

Solved

Custom fields on woocommerce product variations

  • I am using ACF on my sites and it is a great plugin but I ran into an issue. While creating a new product in woocommerce there is an option to set up the product variations. I want to add some custom fields to the variations box, which will be different for each variation and then show them on the front-end. I have attached an image which will give a better idea of what i am trying to say. I want to add some fields on that box. Is it possible to achieve?

    I can add custom meta boxes below the product data box but that will result in being constant for individual variations and different for products. I want the fields to be different for individual variations. Thanks in advance for any help!

    Regards

    • Elliot

    • October 4, 2013 at 1:39 pm

    Hi @scorcher

    This is unfortunately out of scope for the ACF plugin. You will need to read up on the woo-commerce documentation to learn if and how you can extend the custom fields for a variation.

    Thanks
    E

  • Uh, alright. By the way thank you for taking out the time for developing and maintaining such an awesome plugin.

    Thanks again

    • dfarin

    • August 19, 2016 at 11:20 pm

    Any News here?
    I have the same Problem and cant find a solution, i just need the custom fields in the backend.
    If i set a new group with the rule show an Product-Type = Variation i dont get the field.

  • Remi Corson has a non-ACF solution to add extra fields for variation products:
    http://www.remicorson.com/woocommerce-custom-fields-for-variations/
    .. and for simple products:
    http://www.remicorson.com/mastering-woocommerce-products-custom-fields/

    • shaun

    • October 18, 2017 at 6:52 pm

    I was able to add ACF fields to woocommerce product variations using only a couple of actions and a filter.

    // Render fields at the bottom of variations - does not account for field group order or placement.
    add_action( 'woocommerce_product_after_variable_attributes', function( $loop, $variation_data, $variation ) {
        global $abcdefgh_i; // Custom global variable to monitor index
        $abcdefgh_i = $loop;
        // Add filter to update field name
        add_filter( 'acf/prepare_field', 'acf_prepare_field_update_field_name' );
        
        // Loop through all field groups
        $acf_field_groups = acf_get_field_groups();
        foreach( $acf_field_groups as $acf_field_group ) {
            foreach( $acf_field_group['location'] as $group_locations ) {
                foreach( $group_locations as $rule ) {
                    // See if field Group has at least one post_type = Variations rule - does not validate other rules
                    if( $rule['param'] == 'post_type' && $rule['operator'] == '==' && $rule['value'] == 'product_variation' ) {
                        // Render field Group
                        acf_render_fields( $variation->ID, acf_get_fields( $acf_field_group ) );
                        break 2;
                    }
                }
            }
        }
        
        // Remove filter
        remove_filter( 'acf/prepare_field', 'acf_prepare_field_update_field_name' );
    }, 10, 3 );
    
    // Filter function to update field names
    function  acf_prepare_field_update_field_name( $field ) {
        global $abcdefgh_i;
        $field['name'] = preg_replace( '/^acf\[/', "acf[$abcdefgh_i][", $field['name'] );
        return $field;
    }
        
    // Save variation data
    add_action( 'woocommerce_save_product_variation', function( $variation_id, $i = -1 ) {
        // Update all fields for the current variation
        if ( ! empty( $_POST['acf'] ) && is_array( $_POST['acf'] ) && array_key_exists( $i, $_POST['acf'] ) && is_array( ( $fields = $_POST['acf'][ $i ] ) ) ) {
            foreach ( $fields as $key => $val ) {
                update_field( $key, $val, $variation_id );
            }
        }
    }, 10, 2 );

    Adding this code as is to your theme’s functions.php file should enable this functionality for all product variation field groups. The only drawback is that it doesn’t check for more complex rules, and the order and position of field groups are not taken into consideration.

  • @shaun Thanks for sharing your code. This helped a lot – but I am facing the issue with a repeater field. I believe this is not supported with your solution. Do you have a solution for repeater fields as well?

    I know that the value of repeater fields are stored like this pattern in the postmeta database:

    repeaterfieldname_0_fieldname

    Now, when I save my repeater field I get this form in the $_POST[‘acf’] variable. I believe I can not make a connecttion to this structure (repeaterfieldname_0_fieldname), can I? My repeater field is named “product_options”, and the fields are named “component”, “text”, “price”.

    array(2) {
    	 ["field_5aa23edb20eb5"]=> array(2) {
    	  ["5aa24c5eafcd0"]=> array(3) {
    	  	 ["field_5aa23f0020eb6"]=> string(3) "abc"
    	  	 ["field_5aa23f0920eb7"]=> string(4) "abc2"
    	  	 ["field_5aa23f1420eb8"]=> string(2) "12"
    	  } 
    	  ["acfcloneindex"]=> array(3) {
    	  	["field_5aa23f0020eb6"]=> string(0) ""
    	  	["field_5aa23f0920eb7"]=> string(0) ""
    	  	["field_5aa23f1420eb8"]=> string(0) ""
    	  }
    	}
    }

    So basically field_5aa23f0020eb6 is “component” etc. Maybe @elliot has an idea?

    Edit:

    It does work like this, but maybe there is another, more convenient, solution?

    
    foreach ( $fields as $key => $val ) {
    	if (is_array($val)) {
    		foreach ($val as $k => $v) {
    			foreach ($v as $fKey => $fValue) {
    				if ($fKey !== 'acfcloneindex') {
    					$i = add_row($k, $fValue, $variation_id);		
    				}       				
    			}							
    		}
    	} else {
    		update_field( $key, $val, $variation_id );
    	}				
    }
    
    • rchipka

    • March 17, 2018 at 5:49 am

    WooCommerce Product Variations are *all* saved via a single POST request.

    To differentiate between product variation fields, WooCommerce names each field field_name[variation_id] so that it is accessible as $_POST['field_name'][$variation_id].

    ACF field data is located in $_POST['acf'][...] and can only have one of each field.

    ACF’s acf()->input->save_post( $post_id ) method uses $_POST['acf'] data, so it cannot contain fields for another variation.

    We need to allow duplicate ACF fields to exist within a single <form> without having them overwrite each other’s value within $_POST['acf'].

    We can achieve this by renaming the field name prefix acf[...] to acf_varation[variation_id][...] and then set $_POST['acf'] to $_POST['acf_varation'][$variation_id] when saving.

    
    $GLOBALS['wc_loop_variation_id'] = null;
    
    function is_field_group_for_variation($field_group, $variation_data, $variation_post) {
    	return (preg_match( '/Variation/i', $field_group['title'] ) == true);
    }
    
    add_action( 'woocommerce_product_after_variable_attributes', function( $loop_index, $variation_data, $variation_post ) {
    		$GLOBALS['wc_loop_variation_id'] = $variation_post->ID;
    
    		foreach ( acf_get_field_groups() as $field_group ) {
    			if ( is_field_group_for_variation( $field_group, $variation_data, $variation_post ) ) {
    				acf_render_fields( $variation_post->ID, acf_get_fields( $field_group ) );
    			}
    		}
    
    		$GLOBALS['wc_loop_variation_id'] = null;
    	}, 10, 3 );
    
    add_action( 'woocommerce_save_product_variation', function( $variation_id, $loop_index ) {
    		if ( !isset( $_POST['acf_variation'][$variation_id] ) ) {
    			return;
    		}
    
    		$_POST['acf'] = $_POST['acf_variation'][$variation_id];
    
    		acf()->input->save_post( $variation_id );
    	}, 10, 2 );
    
    add_filter( 'acf/prepare_field', function ( $field ) {
    		if ( !$GLOBALS['wc_loop_variation_id'] ) {
    			return $field;
    		}
    
    		$field['name'] = preg_replace( '/^acf\[/', 'acf_variation[' . $GLOBALS['wc_loop_variation_id'] . '][', $field['name'] );
    
    		return $field;
    	}, 10, 1);
    
  • When I use these filter scripts, they allow the repeater fields to display in the variations, but I am having a problem getting them to save. Is there something I am doing wrong? I copied Shaun’s and rchipka’s scripts.

    • J_M

    • March 14, 2019 at 6:00 am

    I don’t see “Product Variations” as a post type, in ACF rules.
    Using latest ACF and latest WC.
    Am I missing something??
    @elliot ?

Viewing 10 posts - 1 through 10 (of 10 total)

You must be logged in to reply to this topic.

We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Cookie Policy. If you continue to use this site, you consent to our use of cookies.