woocommerce_wp_select options array from product attribute terms - php

I am trying to create a drop down list box in woocommerce but have it populated with data from the database.
I have the majority of the code working but the portion to populate the list box is killing me. This is what I have so far.
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' ); // Display Extra Fields on General Tab Section
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_general_fields_save' ); // Save Fields
function woo_add_custom_general_fields() {
global $woocommerce, $post, $product;
echo '<div class="options_group">';
// Select
$options = array(
'hide_empty' => false,
'order' => 'ASC',
'fields' => 'names'
);
$DogBreeds = get_terms('pa_breed', $options);
foreach ($DogBreeds as $key => $value) {
$theArray = "'{$value}' => __( '{$value}' , 'woocommerce' ), ";
}
woocommerce_wp_select(
array(
'id' => '_select',
'label' => __( 'My Select Field', 'woocommerce' ),
'options' => $theArray //this is where I am having trouble
)
);
echo $theArray;
echo '<pre>';
var_dump($DogBreeds);
echo '</pre>';
echo '</div>';
}
// Save Fields
function woo_add_custom_general_fields_save( $post_id ){
// Select
$woocommerce_select = $_POST['_select'];
if( !empty( $woocommerce_select ) )
update_post_meta( $post_id, '_select', esc_attr( $woocommerce_select ) );
else {
update_post_meta( $post_id, '_select', Null );
}
}
This should pull information from the "ATTRIBUTES" section in WooCommerce. I created a Breed Attribute and put a few dog breeds in there.
Any direction is greatly appreciated!
I know the 'options' section on the array is totally wrong but I put it there so you would know what I am trying to accomplish.

I have revisited your code a bit. The main problem was in the select <option> array.
You will see in the code the changes:
// Display Extra Fields on General Tab Section
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' );
function woo_add_custom_general_fields() {
global $post;
// Set HERE the product attribute taxonomy
$taxonomy = 'pa_breed';
// Get the selected value <== <== (updated)
$value = get_post_meta( $post->ID, '_select', true );
if( empty( $value ) ) $value = '';
$dog_breeds = get_terms( $taxonomy, array(
'hide_empty' => false,
'order' => 'ASC',
'fields' => 'names'
) );
$options[''] = __( 'Select a value', 'woocommerce'); // default value
foreach ($dog_breeds as $key => $term)
$options[$term] = $term; // <=== <=== <=== Here the correct array
echo '<div class="options_group">';
woocommerce_wp_select( array(
'id' => '_select',
'label' => __( 'My Select Field', 'woocommerce' ),
'options' => $options, //this is where I am having trouble
'value' => $value,
) );
echo '</div>';
}
// Save Fields
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_general_fields_save' );
function woo_add_custom_general_fields_save( $post_id ){
// Select
$woocommerce_select = $_POST['_select'];
if( !empty( $woocommerce_select ) )
update_post_meta( $post_id, '_select', esc_attr( $woocommerce_select ) );
else {
update_post_meta( $post_id, '_select', '' );
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested in WooCommerce 3+ and works. You will get something similar to this (with your breeds):

This will work for sure:
woocommerce_wp_select(array(
'id' => '_select',
'label' => __('My Select Field', 'woocommerce'),
'options' => array(
'red' => 'Red',
'blue' => 'Blue'
),
));

Related

Add a dropdown based on product categories in Woocommerce admin product variation

I need to replace checkboxes fields with a unique select field to display product categories term names that I get from a child term ID, in admin product variation settings (for my variable products only).
So woocommerce_wp_checkbox() function will be replaced by woocommerce_wp_select() instead.
Here is my WORKING code for checkboxes:
<?php
// Woocommerce Product meta
// Add Variation Settings
add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );
// Save Variation Settings
add_action( 'woocommerce_save_product_variation', 'save_variation_settings_fields', 10, 2 );
// Add fields
function variation_settings_fields( $loop, $variation_data, $variation ) {
// Characteristics
$args = array( 'type' => 'product', 'taxonomy' => 'product_cat', 'child_of' => 20 );
$categories = get_categories( $args );
foreach ($categories as $cat) {
woocommerce_wp_checkbox( array(
"id" => $cat->name .'_['. $variation->ID .']',
"label" => __(" " . $cat->name, "woocommerce" ),
"value" => get_post_meta( $variation->ID, $cat->name .'_', true ),
)
);
}
?>
<?php
}
// Save
function save_variation_settings_fields( $post_id ) {
// Characteristics
$args = array( 'type' => 'product', 'taxonomy' => 'product_cat', 'child_of' => 20 );
$categories = get_categories( $args );
foreach ($categories as $cat) {
$checkbox = isset( $_POST[$cat->name . '_'][ $post_id ] ) ? 'yes' : 'no';
update_post_meta( $post_id, $cat->name . '_', $checkbox );
}
}
?>
How can I replace the checkboxes by a dropdown (OR eventually radio buttons)?
Any help is really appreciated.
In your actual code there is some mistakes like using get_categories() to get product category custom taxonomy terms. Instead just use get_terms()…
The below code will enable a select field instead of multiple checkboxes. The select value is well saved.
The revisited code:
// Add Variation settings custom field
add_action( 'woocommerce_product_after_variable_attributes', 'add_product_category_variation_field', 11, 3 );
function add_product_category_variation_field( $loop, $variation_data, $variation ) {
// Get product categories that are child of term = 20
$terms = get_terms( array('taxonomy' => 'product_cat', 'child_of' => 20 ) );
$options = []; // Initializing
// Loop through each wp_term object and set term names in an array
foreach ($terms as $term) {
$term_name = __( $term->name, "woocommerce" );
$options[$term_name] = $term_name;
}
// The select field
woocommerce_wp_select( array(
'id' => '_product_category',
'name' => "_product_category_$loop",
'label' => __("product categories", "woocommerce" ),
'options' => $options,
'value' => get_post_meta( $variation->ID, '_product_category', true ),
) );
}
// Save Variation settings custom field
add_action( 'woocommerce_save_product_variation', 'save_product_category_variation_field', 11, 2 );
function save_product_category_variation_field( $variation_id, $loop ){
if( isset($_POST["_product_category_$loop"]) )
update_post_meta( $variation_id, '_product_category', esc_attr( $_POST["_product_category_$loop"] ) );
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Add a drop down to product edit pages in product data "General" settings tab

I am trying to figure out how to modify the singe product options so the product admin can pick from the drop down list the condition of product, i.e. new/ used.
Below is a code that allows product admin to enter the condition of product manually.
// Enabling and Displaying Fields in backend
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' );
function woo_add_custom_general_fields() {
global $woocommerce, $post;
echo '<div class="options_group">';
woocommerce_wp_text_input( array( // Text Field type
'id' => '_Stan',
'label' => __( 'Stan', 'woocommerce' ),
'placeholder' => 'i.e: nowa; uzywana...',
'desc_tip' => 'true',
'description' => __( 'Podaj stan plyty.', 'woocommerce' )
) );
echo '</div>'; // Closing </div> tag HERE
}
// Save Fields values to database when submitted (Backend)
add_action( 'woocommerce_process_product_meta', 'woo_save_custom_general_fields' );
function woo_save_custom_general_fields( $post_id ){
// Saving "Conditions" field key/value
$Stan_field = $_POST['_Stan'];
if( !empty( $Stan_field ) )
update_post_meta( $post_id, '_Stan', esc_attr( $Stan_field ) );
}
add_action('woocommerce_single_product_summary', 'woo_display_custom_general_fields_values', 45);
function woo_display_custom_general_fields_values() {
global $product;
echo '<p class="custom-Stan">Stan: ' . get_post_meta( $product->id, '_Stan', true ) . '</p>';
}
There is some errors and mistakes so I have revisited a little bit your code. Now you will have to replace woocommerce_wp_text_input() by woocommerce_wp_select() to get a select field instead, this way:
// Enabling and Displaying Fields in backend
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' );
function woo_add_custom_general_fields() {
echo '<div class="options_group">';
woocommerce_wp_select( array( // Text Field type
'id' => '_Stan',
'label' => __( 'Stan', 'woocommerce' ),
'description' => __( 'Podaj stan plyty.', 'woocommerce' ),
'desc_tip' => true,
'options' => array(
'' => __( 'Select product condition', 'woocommerce' ),
'Nowa' => __('Nowa', 'woocommerce' ),
'Uzywana' => __('Uzywana', 'woocommerce' ),
)
) );
echo '</div>';
}
// Save Fields values to database when submitted (Backend)
add_action( 'woocommerce_process_product_meta', 'woo_save_custom_general_fields', 30, 1 );
function woo_save_custom_general_fields( $post_id ){
// Saving "Conditions" field key/value
$posted_field_value = $_POST['_Stan'];
if( ! empty( $posted_field_value ) )
update_post_meta( $post_id, '_Stan', esc_attr( $posted_field_value ) );
}
// Display In front end
add_action( 'woocommerce_product_meta_start', 'woo_display_custom_general_fields_values', 50 );
function woo_display_custom_general_fields_values() {
global $product;
// compatibility with WC +3
$product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id;
echo '<span class="stan">Stan: ' . get_post_meta( $product_id, '_Stan', true ) . '</span>';
}
Code goes in function.php file of the active child theme (or active theme).
Tested and works.
Is better to avoid capitals in meta keys and they should start with an underscore.

Saving custom field data from Admin WooCommerce product data metabox

In Woocommerce I use some custom fields for product specifications, and save the specifications in the post_meta.
I'm trying to make an if loop to write down in the post_meta another product specification.
The code I now use is:
add_action( 'woocommerce_product_options_general_product_data', 'BTW_field' );
function BTW_field() {
woocommerce_wp_radio(
array(
'id' => '_BTW',
'default' => '21% BTW',
'required' => true,
'options' => array(
'Prijs is incl. 21% BTW' => '21% BTW',
'Margeproduct' => 'Marge Product',
)
)
);
}
add_action( 'woocommerce_process_product_meta', 'BTW_save' );
function BTW_save( $post_id ){
$BTW = $_POST['_BTW'];
if( !empty( $BTW ) )
update_post_meta( $post_id, '_BTW', esc_attr( $BTW ) );
}
An now I try to rewrite the BTW_save function so it will save another post_meta.
function BTW_save( $post_id ){
$BTW = $_POST['_BTW'];
if( !empty( $BTW ) ){
update_post_meta( $post_id, '_BTW', esc_attr( $BTW ) );
}
if ($BTW == "Margeproduct (vrijgesteld van BTW)"){
$BTW2 = "Margeproduct*"
} else {
$BTW2 = "21%"
}
update_post_meta( $post_id, '_BTW_NAME', esc_attr( $BTW2 ) );
}
I don't know how I can check if $BTW is equal to the post_meta _BTW and how I can rewrite it so $BTW2 will also save in the post meta as _BTW_NAME.
Updated: As you are setting 2 different values, it could be better to use a select field instead.
Also I have make some changes in your code regarding correct variable naming and field keys naming (You should be able to rename them easily keeping in mind that lowercase and underscores are recommended).
Here is the code:
add_action( 'woocommerce_product_options_general_product_data', 'add_btw_field' );
function add_btw_field() {
global $post;
// Get the selected value
$value = get_post_meta( $post->ID, '_btw', true );
if( empty( $value ) ) $value = 'btw'; // Default value
woocommerce_wp_select( array(
'id' => 'btw_select',
'label' => __( 'BTW-prijsopties', 'woocommerce' ),
'options' => array(
'btw' => __( '21% BTW', 'woocommerce' ),
'marge' => __( 'Marge Product', 'woocommerce' ),
),
'value' => $value, // Displaying the selected value
) );
}
add_action( 'woocommerce_process_product_meta', 'save_btw_field' );
function save_btw_field( $post_id ){
if( empty( $_POST['btw_select'] ) ) return; // exit (in case of)
update_post_meta( $post_id, '_btw', esc_attr( $_POST['btw_select'] ) );
if ( $_POST['btw_select'] == 'btw' )
$label = __( 'BTW 21%', 'woocommerce' );
else
$label = __( 'Margeproduct (vrijgesteld van BTW)', 'woocommerce' );
update_post_meta( $post_id, '_btw_label', esc_attr( $label ) );
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works. You will get something like that:
By default when creating or updating a product, both custom fields will be saved for 'btw' option as product meta data…
You will be able to get both product post_meta custom fields values using get_post_meta():
// Set HERE the product ID (or get it dynamically)
$product_id = 37;
$btw = get_post_meta( $product_id, '_btw', true ); // Values can be 'yes' or 'no'
$btw_label = get_post_meta( $product_id, '_btw_label', true );
// Output (testing):
echo $btw_label;

WPML - Cart item data custom Fields don't update when switching language

I am using Woocommerce plugin with WPML Multilingual plugin, and I simply can't get to work like I would expect.
My products have serveral Custom Fields that I need to display in the cart, Checkout, Order views and emails notifications.
The Fields are displayed correctly on frontend but when I switch the language the data from sessions are not updated.
How does WPML handle the extra data?
Is there a way to get this to work, that the data update when i switch the language?
Here is my code:
add_filter( 'woocommerce_product_data_tabs', 'mbextra_product_data_tab' , 99 , 1 );
function mbextra_product_data_tab( $product_data_tabs ) {
$product_data_tabs['mbextraproducttab'] = array(
'label' => __( 'EXTRA', 'mbg' ),
'target' => 'mbextraproductdata',
'class' => array();
);
return $product_data_tabs;
}
add_action( 'woocommerce_product_data_panels', 'mbextra_product_data_fields' );
function mbextra_product_data_fields() {
?>
<div id="mbextraproductdata" class="panel woocommerce_options_panel">
<div class="options_group">
<?php
woocommerce_wp_textarea_input(
array(
'id' => 'company',
'label' => __( 'Company', 'mbg' ),
'placeholder' => 'Company Adress here',
'desc_tip' => 'true',
'description' => __( 'Enter Company Adress here', 'mbg' )
)
);
?>
</div>
<div class="options_group">
<?php
woocommerce_wp_textarea_input(
array(
'id' => 'shortdescription',
'label' => __( 'Short-Description', 'mbg' ),
'placeholder' => 'Enter some short info',
'desc_tip' => 'true',
'description' => __( 'Enter Short description here', 'mbg' )
)
);
?>
</div>
</div><!-- #extraproductdata Tab -->
<?php
}
add_action( 'woocommerce_process_product_meta', 'mbprocess_product_meta_fields_save', 99 );
function mbprocess_product_meta_fields_save( $post_id ){
// if set > save the fields
$company = $_POST['company'];
if( isset( $company ) )
update_post_meta( $post_id, 'company', esc_attr( $company ) );
// if set > save data to post_meta
$shortdescription = $_POST['shortdescription'];
if( isset( $shortdescription ) )
update_post_meta( $post_id, 'shortdescription', esc_attr( $shortdescription ) );
}
add_filter( 'woocommerce_add_cart_item_data', 'custom_product_field', 10, 3 );
function custom_product_field( $cart_item_data, $product_id, $variation_id ) {
$shortdesciption = get_post_meta( $product_id , 'shortdesciption' , true );
$company = get_post_meta( $product_id , 'company' , true );
if( !empty( $shortdesciption ) )
{
$cart_item_data['shortdesciption'] = $shortdesciption;
}
if( !empty( $company ) )
{
$cart_item_data['company'] = $company;
}
return $cart_item_data;
}
add_filter( 'woocommerce_get_cart_item_from_session', 'mbget_cart_item_from_session', 10, 3);
function mbget_cart_item_from_session( $cart_item_data, $cart_item_session_data, $cart_item_key ) {
if ( isset( $cart_item_session_data['shortdesciption'] ) ) {
$cart_item_data['shortdesciption'] = $cart_item_session_data['shortdesciption'];
}
if ( isset( $cart_item_session_data['company'] ) ) {
$cart_item_data['company'] = $cart_item_session_data['company'];
}
return $cart_item_data;
}
add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 10, 2 );
function render_meta_on_cart_and_checkout( $cart_data, $cart_item ) {
$data = array();
if( !empty( $data ) ) {
$data = $cart_data;
}
if( isset( $cart_item['shortdesciption'] ) ) {
$data[] = array(
'name' => __( 'Stuff', 'mbg' ),
'value' => $cart_item['shortdesciption'] );
}
if( isset( $cart_item['company'] ) ) {
$data[] = array(
'name' => __( 'Company', 'mbg' ),
'value' => $cart_item['company'] );
}
return $data;
}
Thanks
YES you should need to destroy the cart session or to remove all cart items when switching language. But this kind of case never really happen:
As it is NOT really a customer behavior, adding items in cart (for some language) and then switch to another language before checkout for example.
So this should not be really a problem. This is just the behavior of a developer that is testing an e-commmerce in all possible ways, isn't it?

Updating product post meta data in admin meta box field

I am trying to update WooCommerce product meta data using update_post_meta() function, but it does''t work.
Here is my code:
function woo_add_deal_general_fields_save( $post_id ){
$post_id = (int)$post_id; // tried to convert into integer
$woocommerce_textarea = $_POST['_deal_textarea'];
if( !empty( $woocommerce_textarea ) )
if ( get_post_meta($post_id, '_deal_textarea', FALSE ) ) {
$test= update_post_meta($post_id, '_deal_textarea', $woocommerce_textarea );
} else {
add_post_meta($post_id, '_deal_textarea', $woocommerce_textarea );
}
var_dump($test);exit;
}
If I try it with a fixed product ID, it works:
$test= update_post_meta(70, '_deal_textarea', $woocommerce_textarea );
Why its not working with $post_id, (int)$post_id, & either get_the_ID();?
Here is the part of my code like function calls:
// Display Fields
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' );
// Save Fields
add_action( 'woocommerce_process_product_meta', 'woo_add_deal_general_fields_save' );
function woo_add_custom_general_fields() {
global $woocommerce, $post;
$feature_product=get_post_meta(get_the_ID(), '_featured', true );
if($feature_product=='yes'){
echo '<div class="options_group">';
// Custom fields will be created here...
// Textarea
woocommerce_wp_textarea_input(
array(
'id' => '_deal_textarea',
'label' => __( 'Deal Caption', 'woocommerce' ),
'placeholder' => '',
'description' => __( 'Enter the Deal Product Text value here. (will be shown on home page)', 'woocommerce' )
)
);
echo '</div>';
}
}
Thanks
Here is your revisited tested and fully functional code, based on this answer:
// Inserting a Custom Admin Field in general tab products pages
add_action( 'woocommerce_product_options_general_product_data', 'add_deal_custom_general_product_field' );
function add_deal_custom_general_product_field() {
global $post;
$feature_product = get_post_meta( $post->ID, '_featured', true );
if( $feature_product == 'yes' ){
echo '<div class="options_group">';
woocommerce_wp_textarea_input( array(
'id' => '_deal_textarea',
'label' => __( 'Deal Caption', 'woocommerce' ),
'placeholder' => '',
'description' => __( 'Enter the Deal Product Text value here. (will be shown on home page)', 'woocommerce' )
) );
echo '</div>';
}
}
// Saving the Custom Admin Field in general tab products pages when submitted
add_action( 'woocommerce_process_product_meta', 'save_deal_custom_general_product_field' );
function save_deal_custom_general_product_field( $post_id ){
$wc_field = $_POST['_deal_textarea'];
$feature_product = get_post_meta( $post_id, '_featured', true );
if( !empty($wc_field) && $feature_product == 'yes')
update_post_meta( $post_id, '_deal_textarea', esc_attr( $wc_field ) );
}
The Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works
I don't know where is the bug, but i simplified the code a bit. Please try it:
function woo_add_deal_general_fields_save( $post_id ){
$woocommerce_textarea = $_POST['_deal_textarea'];
if( !empty( $woocommerce_textarea ) ) {
$test = update_post_meta( $post_id, '_deal_textarea', $woocommerce_textarea );
var_dump( $test ); exit;
}
}

Categories