Home Forums WC Vendors Pro Support Adding a Custom Field for Products – Multi-Selects, Arrays and Taxonomies Oh My!

NOTICE: We've Moved to a Ticket System for Support

As of August 31, 2017 (12am EST) our support forums will be retired (read-only), and we will be moving to a support ticket system.  This will allow us to better organize and answer support requests, and provide a more personalized experience as we assist our customers.

For the time being, we will leave our forums open for reading and learning while we work on creating a more robust Knowledge Base for everyone to use.

If you are a WC Vendors Pro customer please open a support ticket here. 

If you are a WC Vendors user please open a support ticket on the Wordpress.org forums.

The information on this forum is outdated and in most instances no longer relevant. Please be sure to check our documentation for the most up to date information.

https://docs.wcvendors.com/

Thank you to all of our customers!

 

Viewing 10 posts - 1 through 10 (of 10 total)
  • Author
    Posts
  • #38040
    Daniel
    Participant

    Hello,

    We’re having some difficulty with the select & select2 custom field inputs on the add product form. The problems seem complex, and so I’ll do my best to explain here, hoping that the solution may be simpler than it’s seemed over the last few days.

    We’ve had to engage these problems with the diligence of scientists, considering that there seem to be a number of variables, so here goes.

    Text fields and Textarea fields saving to wcv_custom_product_fields seem to work just fine. The problems start when we attempt to

    1) Use select or select2 input types to assign arrays to custom fields
    2) Use select or select2 input types to assign single values or arrays to taxonomies.

    There seems to be no documentation on how to build the inputs in the product-edit.php file or how to get associated functions to save and or call the values properly, unless we’ve been looking in the wrong place.

    Additionally, when we use select or select2 input types, we’re finding, depending upon how the custom field variables are setup, that the values either aren’t saved, or are saved but in the wrong configuration, and/or perhaps in the wrong place.

    In several situations, we found that values didn’t appear in the form on refresh, but that the values were indeed saved to the database… we were able to call these values on the product page using get_post_meta… and that simultaneously, the values were not added to the taxonomy as evidenced on the back end.

    Here’s the code we used for the test field (now set up to save values to a taxonomy, at least that’s what we’re trying to do):

    in product-edit.php:

    			// Food Type Custom Field
    			WCVendors_Pro_Form_Helper::select2( array(  
    				 'type'      => 'text',
    				 'post_id'   => $object_id, 
    				 'id'     => 'wcv_custom_product_food_type[]', 
    	   			 'taxonomy'	=> 'food_type',
    				 'taxonomy_args'	=> array( 'hide_empty'=>false ),
    				 'label'    => __( 'Food Type (Select all that apply)', 'wcvendors-pro' ), 
    				 'placeholder'   => __( 'Food Type', 'wcvendors-pro' ), 
    				 'desc_tip'    => 'false', 
    				 'custom_attributes' => array( 'multiple' => 'multiple' )
    			) );

    In functions.php:

    // Food Type
    add_action('woocommerce_product_meta_start', 'wcv_food_type', 2);
    function wcv_food_type() {
        $food_types = get_post_meta( get_the_ID(), 'wcv_custom_product_food_type', false ); // Set the meta key
    	echo 'food_types = ' . $foodtypes;
    	// If top level array exists
    	foreach ($food_types as $key => $value) : 
    		echo 'food_types' . $key . ' => ' . $value . '<br>';
    	endforeach;
    	echo '<br>';
    	// If contained array exists
    	foreach ($food_types[0] as $key => $value) : 
    		echo 'food_types[0]' . $key . ' => ' . $value . '<br>';
    	endforeach;
    	echo '<br>';
    }

    The functions.php function here echoing so many variations is to test where the data is being saved, and how. It’s definitively not being saved as taxonomy terms, as desired, though the custom field is clearly calling in the taxonomy terms and assigning the values to an array somewhwere. Here’s what appears on the product page (the current variable declarations are not saving):

    food_types = 
    
    Warning: Invalid argument supplied for foreach() in /home/yogibl5/public_html/wpdev/wp-content/themes/dazzling-child/functions.php on line 74

    So here are screen shots of our “test results”:

    The first test

    The first test

    And the second. Note that the behaviors when we linked to taxonomy didn’t seem to remain consistent

    The second test

    The short of it, is we’d like to know how to do this right. We’d like to be able to save multiple values to a taxonomy’s terms from the product form, have them save to the taxonomy, and refresh when the product form is reloaded. It’s not clear now, how….

    Thanks.

    #38041
    Daniel
    Participant

    Ok, the images are failing… trying this link to the public google drive folder.

    https://drive.google.com/open?id=0B9L_6DOCutEEOUN6X3l2c3ZaTmM

    #38073
    Lars
    Participant

    Hi Daniel,

    I think I can help you somewhat in the right direction.
    There are previous posts, such as this one
    WC Vendors – Form helper multi select
    which detail the entire process.

    Basically, in as far as I’ve got my own code working, I understand this process to be as follows:
    – save the value/array in a custom wcv_custom or _wcv_custom attribute
    – afterwards copy the values to the correct taxonomy, attribute, etc. in a custom function / hook

    (Custom taxonomies in attributes do mess up some links if added automatically, but that is to be expected. Other than that, the snippet in the previous post does the trick very nicely.)

    If the previous post doesn’t help you out, please don’t hesitate to message back.
    And I’ll see if my limited code can help 🙂

    #38116
    WC Vendors Support
    Participant

    Thanks Lars for your help. Only one thing to add: You can use wcv_custom_whatever and _wcv_custom_whatever, the difference is the underscore _ . If the meta key is _wcv_custom_whatever1 then the _ in the beginning means it is a hidden custom field, and that means admins can not see it when editing a product. If you used wcv_custom_whatever1 then no underscore means you would see it in the Custom Fields meta box of wp-admin when editing the product.

    Beyond that, you’re good to go!

    #38244
    Daniel
    Participant

    Lars & Ben,

    Thanks for your help…. I think we’ve clarified the problem somewhat, but still not getting what’s needed here. Here’s the current code:

    in Product-edit.php:

    			$food_type_value = get_post_meta( $object_id, 'wcv_custom_product_food_type', true );
    			$food_type_options = array (  
    				'vegan'   => __( 'Vegan', 'wcvendors-pro' ),  
    				'vegetarian'   => __( 'Vegetarian', 'wcvendors-pro' ),  
    				'raw'      => __( 'Raw', 'wcvendors-pro' ),
    				'organic'      => __( 'Organic', 'wcvendors-pro' ),
    				'gluten-free'      => __( 'Gluten Free', 'wcvendors-pro' ),	
    			); 
    			
    			WCVendors_Pro_Form_Helper::select( apply_filters( 'wcv_custom_product_food_type', array( 
    				'post_id'			=> $object_id, 
    				'id' 				=> 'wcv_custom_product_food_type[]', 
    				'label'   			=> __( 'Food Type (Select all that apply)', 'wcvendors-pro' ), 
    				'placeholder'   	=> __( 'Food Type', 'wcvendors-pro' ), 
    				'wrapper_start' 	=> '<div class="all-100">',
    				'wrapper_end' 		=> '</div>', 
    				'desc_tip'   		=> 'false', 
    				'taxonomy'			=> 'food_type',
    				'taxonomy_args'		=> array( 'hide_empty'=>false ),
    				'custom_attributes' => array( 'multiple' => 'multiple' ),
    				'options' 			=> $food_type_options,  
    				'value'             => $food_type_value
    				) )
    			);

    and in Functions.php:

    // Food Type
    add_action('woocommerce_product_meta_start', 'wcv_food_type', 2);
    function wcv_food_type() {
        $food_types = get_post_meta( get_the_ID(), 'wcv_custom_product_food_type', true ); // Set the meta key
    	// If top level array exists
    	foreach ($food_types as $key => $value) : 
    		echo 'food_types' . $key . ' => ' . $value . '<br>';
    	endforeach;
    	echo '<br>';
    }
    
    add_action( 'wcv_save_product_meta', 'food_type_save_product_meta', 10, 1 );
    function food_type_save_product_meta ( $product_id ) {
    
    	// product meta - usage food type
    	if ( isset( $_POST[ 'wcv_custom_food_type' ] ) ) { 
    
    		$food_types = $_POST[ 'wcv_custom_food_type' ];
    		print_r( $food_types);
    
    		if ( ! empty( $food_types ) ) {
    			foreach ( $food_types as $food_type ) { $food_type = wc_clean( $food_type ); }
    			update_post_meta( $product_id, 'wcv_custom_food_type', $food_types ); 
    			update_post_meta( $product_id, 'food_type', $food_types ); 
    		} else {
    			delete_post_meta( $product_id, 'wcv_custom_food_type' );
    			delete_post_meta( $product_id, 'food_type' );    
    		}
    	}    
    }			

    Here’s what’s being reported in the Product Page:

    
    food_types0 => 30
    food_types1 => 29
    

    The code is apparently saving the selected ‘food_type’ taxonomy terms to the ‘wcv_custom_product_food_type’ array variable when the vendor adds the options in the product-edit form, and the numerical array values being echoed on the product page are the ID’s of the taxonomy terms. However, the selected options/tax terms are not actually being added to the product from what I can tell on the back end, or on the product-edit form on reload. The terms are not checked on the ‘food_type’ taxonomy’s metabox in the product/post back end editor after saving. They’re also not appearing in the admin column on the back end woocommerce ‘products’ listing page. So… something is still missing, or maybe 2 things are.

    First, I’m suspecting that the option values echoed on the front-end product page should be taxonomy term names, and not their numerical values. The numerical values seem to be what’s being saved as the ‘value’ part of the ‘key/value’ pair, and I’m not sure why. Maybe that’s the whole problem?

    Second, perhaps the values are not being passed properly from the ‘wcv_custom_product_food_type’ variable to the actual ‘food_type’ taxonomy?

    I’m not sure why, still getting my sea legs with PHP, and probably need some hand holding here.

    Thanks!

    #38245
    Daniel
    Participant

    Caught the error in my last post – ‘wcv_custom_food_type’ should be ‘wcv_custom_product_food_type.’ Fixed that; no change in behavior. Thx.

    #38277
    Lars
    Participant

    Hi Daniel,

    unfortunately there’s a lot of work on my own site here.
    So I’m not going to be able to troubleshoot your code.

    But to balance that out, here is my code, for adding a select field for all custom taxonomies created on the back end (which in my opinion is more easily maintained and checked).

    Add this to functions.php

    add_action( 'wcv_save_product_meta', 'riv_pro_save_product_meta', 10, 1 );
    function riv_pro_save_product_meta ( $product_id ) {
        
            $defaults = array();
            $attribute_taxonomies = wc_get_attribute_taxonomies();
            $i=0;
            
    	foreach ($attribute_taxonomies as $tax) {
    		$name = wc_attribute_taxonomy_name($tax->attribute_name);
    		$sname = substr($name,3);
    		$wcv_name = '_wcv_custom_product_'.$sname;
    		$wcv_value = $_POST[ $wcv_name ];
    		
    		
    		
    		if ( isset( $_POST[ $wcv_name ] ) ) { 
    				
    			$defaults[$name]= array(
    				'name'	=> $name,
    				'value'	=> '',
    				'position' => $i,
    				'is visible' => 1,
    				'is variation' => 0,
    				'is_taxonomy' =>1,
    				);
    			update_post_meta($product_id, '_product_attributes', $defaults );
    			
    			
    			if( !empty($wcv_value)){
    				//update_post_meta( $product_id, $wcv_name, '' );
    				foreach ($wcv_value as $value) {
    					$value = wc_clean($value);
    					}
    				$term = get_term($wcv_value[0],$name);
            			$v = $term->name;
    				update_post_meta( $product_id, $wcv_name, $wcv_value[0]);
    				wp_set_object_terms($product_id, $v, $name,  false);
    				}
    			else { 	delete_post_meta($product_id,$wcv_name,$wcv_value[0]);}
    			
    			}
    		$i++;
    		}
    		    //$s = wp_set_object_terms($product_id, '64', 'pa_merk', false);
    		    //print_r ($s);
    	 } 
    

    And this on the product-edit.php side:

    
    	$attribute_taxonomies = wc_get_attribute_taxonomies();
    	foreach ($attribute_taxonomies as $tax) {
    		$wcv_name = '_wcv_custom_product_'.substr(wc_attribute_taxonomy_name($tax->attribute_name),3);
    		$wcv_value = (array)get_post_meta( $object_id, $wcv_name, true );
    		$wcv_tax = wc_attribute_taxonomy_name($tax->attribute_name);
    		$wcv_label = ucfirst(substr(wc_attribute_taxonomy_name($tax->attribute_name),3));
            
            WCVendors_Pro_Form_Helper::select( apply_filters( $wcv_name, array( 
    			'post_id'			=> $object_id, 
    			'id' 				=> $wcv_name.'[]', 
    			'label' 			=> __( $wcv_label, 'wcvendors-pro' ), 
    			'wrapper_start' 	=> '<div class="all-100">',
    			'wrapper_end' 		=> '</div>', 
    			'taxonomy'	=> $wcv_tax,
    			'is_taxonomy'	=> true,
    			'taxonomy_args'		=> array( 
    						'hide_empty'	=> 0, 
    						'orderby'		=> 'order' 
    							), 
                		'value'             => $wcv_value
    			) )
            );
            }
    

    As previously mentioned, this does require that you have your custom taxonomies set up on the back end with a number of terms in each (and that your vendor has the correct capabilities to add these to a woocommerce product – was one thing that kept me hung up for a while).

    Anyway, I hope you’ve got something valuable out of this. (And if you get the multi select working, I’d be more than interested. Somehow I feel you’ll want them to be able to select both gluten free and vegan at the same time.)

    Take care.

    Lars

    #38291
    Daniel
    Participant

    Thanks Lars! I’m going to be spending a bit of time with this later in the afternoon. I’ll share back here on results and/or issues, as I’m certain that this thread will be useful to others too.

    #38594
    Daniel
    Participant

    FYI,

    I figured out a solution that works for our needs. This is a solution that gets a multi-select field to integrate with a custom taxonomy – basically every time the vendor updates the wc-vendor field multi-select field in the front-end product-edit.php form and saves, the taxonomy terms get updated too. When an admin changes the taxonomy terms via the taxonomy’s metabox on the back end product editor, the array value of the WC Vendor custom field is not updated with the code as it is here. For our purposes, that’s fine, since the code does pull the terms from the taxonomy to populate both the front end product page, and the edit-product form next time the vendor goes to edit the product.

    Noting too that this solution isn’t as elegant as Lars’s yet, since it only handles one multi-select custom field + taxonomy at a time, but it’s a good prototype that can be generalized later.

    First, create the taxonomy and the terms using a plugin like Custom Post Types UI, or if you’re the hardcode type, create it yourself.

    And then here’s the code (set up for our Food Types taxonomy, but replace that with whatever you like:

    In Functions.php or a custom plugin…

      
    // Food Type - Array/Taxonomy-Connected Field
    add_action('woocommerce_product_meta_start', 'wcv_food_type', 2);
    function wcv_food_type() {
    	$gid = get_the_ID();
        $food_types = get_post_meta( $gid, 'wcv_custom_product_food_type', true ); // Set the meta key
    	$food_types_terms = (array)get_the_terms( $gid, 'food_type' );
    
    	echo '<h3>Food Types</h3>';
    
    	// Note that this calls the Taxonomy that's associated with the WC Vendors variable
    	foreach ($food_types_terms as $key => $value) {
    		$food_types_term = get_term( $value , 'food_type' );
    		$h = $food_types_term->name;
    		$i = wc_clean($h);
    		echo $i . '<br>';
    	 }
    	echo '<br>';
    }
    
    add_action( 'wcv_save_product_meta', 'food_type_save_product_meta', 10, 1 );
    function food_type_save_product_meta ( $product_id ) {
    	
    	$food_types_names = array();												      // Create an array that will recieve the tax names
    	
    	if ( isset( $_POST[ 'wcv_custom_product_food_type' ] ) ) { 
    
       		$food_types = get_post_meta( $product_id, 'wcv_custom_product_food_type', true ); // Get the wcv array values
    		
    		if ($food_types) {
    		
    			foreach ($food_types as $key => $value) {
    				$food_type_name = get_term( $value , 'food_type' );
    				$f = $food_type_name->name;
    				$g = wc_clean($f);
    				$food_types_names[] = $g;
    			}
    			wp_set_object_terms( $product_id, $food_types_names , 'food_type' );
    			}	}
    		
    	else {
    		delete_post_meta( $product_id, 'wcv_custom_product_food_type' );			// delete the contents of the wcv variable
    		wp_set_object_terms( $product_id, NULL , 'food_type' );  					// and delete the contents of the taxonomy			
    		}			
    	}	
    

    and in product-edit.php…

    
    			// Food Type Custom Field
    			
    			$food_type = (array)get_the_terms( $object_id, 'food_type' );
    			
    			WCVendors_Pro_Form_Helper::select2( apply_filters( 'wcv_custom_product_food_type', array( 
    				'post_id'			=> $object_id, 
    				'id' 				=> 'wcv_custom_product_food_type[]', 
    				'label'   			=> __( 'Food Type (Select all that apply)', 'wcvendors-pro' ), 
    				'placeholder'   	=> __( 'Food Type', 'wcvendors-pro' ), 
    				'wrapper_start' 	=> '<div class="all-100">',
    				'wrapper_end' 		=> '</div>', 
    				'desc_tip'   		=> 'false', 
    				'taxonomy'			=> 'food_type',
    				'taxonomy_args'		=> array( 'hide_empty'=>false ),
    				'value' 			=> $food_type,
    				'custom_attributes' => array( 'multiple' => 'multiple' )
    				
    				) )
    			);	
    

    Note also that for the ability to multi-select, for us it seemed only to work with the ‘select2’ input class, and not at all with the ‘select’ class.

    Hope this is of service.

    #64861
    Samia
    Participant

    I have applied your solution and it works like charm for me. But now I would like to restrict multi-select for my custom taxonomies. How I can do this. Thanks

Viewing 10 posts - 1 through 10 (of 10 total)
  • The forum ‘WC Vendors Pro Support’ is closed to new topics and replies.