Support

Account

Forum Replies Created

  • 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);
    
Viewing 1 post (of 1 total)