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.
Thank you to all of our customers!
- This topic has 9 replies, 4 voices, and was last updated 6 years, 11 months ago by Samia.
-
AuthorPosts
-
July 24, 2016 at 1:11 am #38040DanielParticipant
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
And the second. Note that the behaviors when we linked to taxonomy didn’t seem to remain consistent
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.
July 24, 2016 at 1:14 am #38041DanielParticipantOk, the images are failing… trying this link to the public google drive folder.
https://drive.google.com/open?id=0B9L_6DOCutEEOUN6X3l2c3ZaTmM
July 25, 2016 at 1:09 am #38073LarsParticipantHi 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 🙂July 25, 2016 at 1:17 pm #38116WC Vendors SupportParticipantThanks 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!
July 26, 2016 at 11:18 pm #38244DanielParticipantLars & 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!
July 26, 2016 at 11:24 pm #38245DanielParticipantCaught the error in my last post – ‘wcv_custom_food_type’ should be ‘wcv_custom_product_food_type.’ Fixed that; no change in behavior. Thx.
July 27, 2016 at 1:42 pm #38277LarsParticipantHi 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
July 27, 2016 at 5:54 pm #38291DanielParticipantThanks 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.
July 31, 2016 at 12:21 am #38594DanielParticipantFYI,
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.
May 11, 2017 at 2:49 am #64861SamiaParticipantI 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
-
AuthorPosts
- The forum ‘WC Vendors Pro Support’ is closed to new topics and replies.