Woocommerce custom_fields(Shipping and Billing) in email_order_meta_fields - woocommerce

I'm trying to store custom shipping and billing fields in order and then to be print in emails ( admin & customer ) but with no success , is there anyone with big heart to help me ?
So as you can see i removed some fields , added other fields in Shipping & Billing then i try to store data of order and at the last i try to send my extra fields in order_email .
Here is my code in functions.php
// Replace billing_email with shipping_email " This because custome don recieve email notification if don't ask invoice "
add_action('woocommerce_checkout_update_order_meta', 'set_billing_email_from_shipping_email', 50, 2 );
function set_billing_email_from_shipping_email( $order_id, $data ) {
// Get customer shipping email
$email = get_post_meta( $order_id, '_shipping_email', true );
// Set billing email from shipping email
update_post_meta( $order_id, '_billing_email', $email );
}
// Remove fields
add_filter( 'woocommerce_checkout_fields', 'wc_remove_checkout_fields' );
function wc_remove_checkout_fields( $fields ) {
// Billing fields
unset( $fields['billing']['billing_first_name'] );
unset( $fields['billing']['billing_last_name'] );
unset( $fields['billing']['billing_address_2'] );
// Shipping fields
unset( $fields['shipping']['shipping_address_2'] );
unset( $fields['shipping']['shipping_company'] );
// Order fields
unset( $fields['order']['order_comments'] );
return $fields;
}
//Add custom fields
add_filter( 'woocommerce_shipping_fields' , 'custom_shipping_fields' );
function custom_shipping_fields( $fields ) {
$fields['shipping_email'] = array(
'label' => __( 'Email', 'woocommerce' ),
'required' =>true,
'class' => array( 'form-row-last' ),
'validate' => array( 'email' ),
);
$fields['shipping_phone'] = array(
'label' => __( 'Telefono', 'woocommerce' ),
'required' => true,
'class' => array( 'form-row-first' ),
'clear' => true,
'validate' => array( 'phone' ),
);
$fields['shipping_invoice'] =array(
'type' => 'checkbox',
'class' => array('form-row-four'),
'label' => __(' Fattura ?'),
'label_class' => array('woocommerce-form__label l_checkbox'),
'input_class' => array('woocommerce-form__input woocommerce-form__input-checkbox i_checkbox'),
);
return $fields;
}
add_filter( 'woocommerce_billing_fields' , 'custom_billing_fields' );
function custom_billing_fields( $fields ) {
$fields['billing_vat'] = array(
'label' => __( 'P.Iva/CF', 'woocommerce' ),
'required' =>false,
'class' => array( 'form-row-last' ),
);
return $fields;
};
function custom_shipping_save_extra_checkout_fields( $order_id, $posted ){
if( isset( $posted['custom_shipping_fields'] ) ) {
update_post_meta( $order_id, '_custom_shipping_fields', sanitize_text_field( $posted['_custom_shipping_fields'] ) );
}
}
function custom_billing_save_extra_checkout_fields( $order_id, $posted ){
if( isset( $posted['custom_shipping_fields'] ) ) {
update_post_meta( $order_id, '_custom_shipping_fields', sanitize_text_field( $posted['_custom_shipping_fields'] ) );
}
}
add_action( 'woocommerce_checkout_update_order_meta', 'custom_save_extra_checkout_fields', 10, 2 );
function custom_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
$fields['custom_shipping_fields'] = array(
'label' => __( 'Custom Siping Fields' ),
'value' => get_post_meta( $order->id, '_custom_shipping_fields', true ),
);
return $fields;
}
add_filter('woocommerce_email_order_meta_fields', 'custom_email_order_meta_fields', 10, 3 );
Thank you!

Related

Hide specific WooCommerce products based on product category for users under the age of 18

I want to hide specific products, based on product category for users under the age of 18.
So if the user is not logged in, or if logged in but under the age of 18 years old (date of birth will be set during check out), these products should be hidden on WooCommerce shop and archive pages.
Via code I found online, and trial and error, this is my code attempt:
add_filter( 'woocommerce_product_categories_hide_empty', 'hide_empty_categories' );
function hide_empty_categories( $hide_empty ) {
if ( is_user_logged_in() ) {
$current_user = wp_get_current_user();
$age = (int) $current_user->user_age;
if ( $age < 18 ) {
$hide_empty = true;
}
}
return $hide_empty;
}
Unfortunately without the desired result. Any advice?
To add the birthday field, I use:
function new_add_custom_checkbox_fields() {
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
$chosen_shipping = $chosen_methods[0];
if ($chosen_shipping != 'free_shipping:2'){
add_filter('woocommerce_checkout_fields', function($fields) {
$fields['billing']['billing_date_intervention'] = [
'label' => __('date du jour', 'textdomain'),
'required' => true,
'type' => 'text',
'default' => date("d/m/Y"),
'class' => ['wooccm-required-field'],
'priority' => 125
];
$fields['billing']['billing_date_naissance'] = [
'label' => __('date de naissance', 'textdomain'),
'required' => true,
'type' => 'date',
'class' => ['wooccm-required-field'],
'id' => 'date_of_birth',
'priority' => 70
];
return $fields;
});
}
}
add_action('woocommerce_billing_fields', 'new_add_custom_checkbox_fields');
/**
* Ajout et mise à jour des champs dans la base de donnée
*/
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['billing_date_intervention'] ) ) {
add_post_meta( $order_id, '_billing_date_intervention', sanitize_text_field( $_POST['billing_date_intervention'] ) );
}
if ( ! empty( $_POST['billing_date_naissance'] ) ) {
add_post_meta( $order_id, '_billing_date_naissance', sanitize_text_field( $_POST['billing_date_naissance'] ) );
}
}
If you want to determine the age, it is first and foremost important to make a field available in WooCommerce, so that a user can enter his date of birth
An important note is that you should save data as user_meta and not as post_meta
So to add and save the field, use:
// Display billing birthdate field to checkout and my account addresses
function filter_woocommerce_billing_fields( $fields ) {
$fields['billing_birthdate'] = array(
'type' => 'date',
'label' => __( 'Birthdate', 'woocommerce' ),
'class' => array( 'form-row-wide' ),
'priority' => 25,
'required' => true,
'clear' => true,
);
return $fields;
}
add_filter( 'woocommerce_billing_fields', 'filter_woocommerce_billing_fields', 10, 1 );
// Save/update user data from custom field value
function action_woocommerce_checkout_update_customer( $customer, $data ) {
// Isset
if ( isset( $_POST['billing_birthdate'] ) ) {
$customer->update_meta_data( 'billing_birthdate', sanitize_text_field( $_POST['billing_birthdate'] ) );
}
}
add_action( 'woocommerce_checkout_update_customer', 'action_woocommerce_checkout_update_customer', 10, 2 );
To hide the desired products, belonging to certain categories in frontend, based on age. You can then use the woocommerce_product_query_tax_query hook.
So you get:
function filter_woocommerce_product_query_tax_query( $tax_query, $query ) {
// The desired product category slug(s)
$categories = array( 'categorie-1', 'categorie-2' );
// Initialize
$flag = true;
// Logged in (not logged in, hide products by default)
if ( is_user_logged_in() ) {
// Get user ID
$user_id = get_current_user_id();
// Get meta
$billing_birthdate = get_user_meta( $user_id, 'billing_birthdate', true );
// NOT empty (when empty, hide products by default)
if ( ! empty( $billing_birthdate ) ) {
// Older than 18
if ( time() > strtotime ( '+18 years', strtotime( $billing_birthdate ) ) ) {
$flag = false;
}
}
}
// When true
if ( $flag ) {
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $categories,
'operator' => 'NOT IN'
);
}
return $tax_query;
}
add_filter( 'woocommerce_product_query_tax_query', 'filter_woocommerce_product_query_tax_query', 10, 2 );

Multiple SKU's for 1 item [duplicate]

We needed another field in our products for Prod ref/Cat numbers and I found the bit of code below which works perfectly.
I now need to add a second field for Nominal Codes used by the accountants software.
I tried using the below code again, adjusted for the new field, but it didn't work.
function jk_add_custom_sku() {
$args = array(
'label' => __( 'Custom SKU', 'woocommerce' ),
'placeholder' => __( 'Enter custom SKU here', 'woocommerce' ),
'id' => 'jk_sku',
'desc_tip' => true,
'description' => __( 'This SKU is for internal use only.', 'woocommerce' ),
);
woocommerce_wp_text_input( $args );
}
add_action( 'woocommerce_product_options_sku', 'jk_add_custom_sku' );
function jk_save_custom_meta( $post_id ) {
// grab the SKU value
$sku = isset( $_POST[ 'jk_sku' ] ) ? sanitize_text_field( $_POST[ 'jk_sku' ] ) : '';
// grab the product
$product = wc_get_product( $post_id );
// save the custom SKU meta field
$product->update_meta_data( 'jk_sku', $sku );
$product->save();
}
add_action( 'woocommerce_process_product_meta', 'jk_save_custom_meta' );
Adding extra fields can be done in a very simple way:
function jk_add_custom_sku() {
$args_1 = array(
'label' => __( 'Custom SKU', 'woocommerce' ),
'placeholder' => __( 'Enter custom SKU here', 'woocommerce' ),
'id' => 'jk_sku',
'desc_tip' => true,
'description' => __( 'This SKU is for internal use only.', 'woocommerce' ),
);
woocommerce_wp_text_input( $args_1 );
// Extra field
$args_2 = array(
'label' => __( 'Nominal codes', 'woocommerce' ),
'placeholder' => __( 'Enter nominal codes here', 'woocommerce' ),
'id' => '_nominal_codes',
'desc_tip' => true,
'description' => __( 'This is for nominal codes.', 'woocommerce' ),
);
woocommerce_wp_text_input( $args_2 );
}
add_action( 'woocommerce_product_options_sku', 'jk_add_custom_sku' );
// Save
function jk_save_custom_meta( $product ){
if( isset($_POST['jk_sku']) ) {
$product->update_meta_data( 'jk_sku', sanitize_text_field( $_POST['jk_sku'] ) );
}
// Extra field
if( isset($_POST['_nominal_codes']) ) {
$product->update_meta_data( '_nominal_codes', sanitize_text_field( $_POST['_nominal_codes'] ) );
}
}
add_action( 'woocommerce_admin_process_product_object', 'jk_save_custom_meta', 10, 1 );

Display product category on the WooCommerce checkout page

I'm trying to add the product category to the below (working) code but I'm not sure how to go about it.
I've tried using product_cat but as I'm not that experienced with php, I'm just guessing how to achieve this.
add_filter( 'woocommerce_get_item_data', 'display_custom_product_field_data', 10, 2 );
function display_custom_product_field_data( $cart_data, $cart_item ) {
$meta_keys = array('time','date');
$dictionary = array('time'=>'Time:','date'=>'Date:' );
$product_id = $cart_item['product_id'];
foreach($meta_keys as $key=>$meta_key){
$meta_value = get_post_meta( $product_id, $meta_key, true );
if( !empty( $cart_data ) ) $custom_items = $cart_data;
if( !empty($meta_value) ) {
$custom_items[] = array(
'key' => __( $dictionary[$meta_key] , 'woocommerce'), //or user $meta_key
'value' => $meta_value,
'display' => $meta_value,
);
}
}
return $custom_items;
}
Following code will also display the product categories on the WooCommerce checkout page
function display_custom_product_field_data( $cart_item_data, $cart_item ) {
// Product ID
$product_id = $cart_item['product_id'];
// Get post meta
$time = get_post_meta( $product_id, 'time', true );
// NOT empty
if( ! empty( $time ) ) {
$cart_item_data[] = array(
'key' => __( 'Time', 'woocommerce'),
'value' => $time,
);
}
// Get terms
$term_names = wp_get_post_terms( $product_id, 'product_cat', array( 'fields' => 'names' ) );
if( ! empty( $term_names ) ) {
$cart_item_data[] = array(
'key' => __( 'Categories', 'woocommerce'),
'value' => implode( ", ", $term_names )
);
}
// Get post meta
$date = get_post_meta( $product_id, 'date', true );
// NOT empty
if( ! empty( $date ) ) {
$cart_item_data[] = array(
'key' => __( 'Date', 'woocommerce'),
'value' => $date,
);
}
return $cart_item_data;
}
add_filter( 'woocommerce_get_item_data', 'display_custom_product_field_data', 10, 2 );

Wordpress Woocommerce custom field

I'm trying to create custom field in woo-commerce (not interested in plugins) in single product and variable product ( custom field price should change according to selected variable option) as that client should be able to enter price as show in 1st picture and customer could be able check the option.
My Requirement
// Display Fields
add_action( 'woocommerce_product_options_general_product_data', 'woocom_general_product_data_custom_field' );
function woocom_general_product_data_custom_field() {
// Create a custom text field
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_text_field',
'label' => __( 'Enter your choose', 'woocommerce' ),
'placeholder' => 'Custom text field',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' )
)
);
// Number Field
woocommerce_wp_text_input(
array(
'id' => '_number_field',
'label' => __( 'Enter your number', 'woocommerce' ),
'placeholder' => '',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'type' => 'number',
'custom_attributes' => array(
'step' => 'any',
'min' => '15'
)
)
);
// Checkbox
woocommerce_wp_checkbox(
array(
'id' => '_checkbox',
'label' => __('Select', 'woocommerce' ),
'description' => __( 'Check me!', 'woocommerce' )
)
);
// Select
woocommerce_wp_select(
array(
'id' => '_select',
'label' => __( 'option', 'woocommerce' ),
'options' => array(
'1' => __( 'Custom Option 1', 'woocommerce' ),
'2' => __( 'Custom Option 2', 'woocommerce' ),
'3' => __( 'Custom Option 3', 'woocommerce' )
)
)
);
// Textarea
woocommerce_wp_textarea_input(
array(
'id' => '_textarea',
'label' => __( 'Description', 'woocommerce' ),
'placeholder' => '',
'description' => __( 'Enter the custom value here.', 'woocommerce' )
)
);
}
// Hook to save the data value from the custom fields
add_action( 'woocommerce_process_product_meta', 'woocom_save_general_proddata_custom_field' );
add_action( 'woocommerce_single_product_summary', 'woocommerce_template_top_category_desc', 1 );
function woocommerce_template_top_category_desc (){
$terms = get_the_terms( $post->ID, 'wc-attibute-class' );
if ( !empty($terms)) {
$term = array_pop($terms);
$text= get_field('txt-field', $term);
if (!empty($text)) {
echo $text;
}
}
}
/** Hook callback function to save custom fields information */
function woocom_save_general_proddata_custom_field( $post_id ) {
// Save Text Field
$text_field = $_POST['_text_field'];
if( ! empty( $text_field ) ) {
update_post_meta( $post_id, '_text_field', esc_attr( $text_field ) );
}
// Save Number Field
$number_field = $_POST['_number_field'];
if( ! empty( $number_field ) ) {
update_post_meta( $post_id, '_number_field', esc_attr( $number_field ) );
}
// Save Textarea
$textarea = $_POST['_textarea'];
if( ! empty( $textarea ) ) {
update_post_meta( $post_id, '_textarea', esc_html( $textarea ) );
}
// Save Select
$select = $_POST['_select'];
if( ! empty( $select ) ) {
update_post_meta( $post_id, '_select', esc_attr( $select ) );
}
// Save Checkbox
$checkbox = isset( $_POST['_checkbox'] ) ? 'yes' : 'no';
update_post_meta( $post_id, '_checkbox', $checkbox );
// Save Hidden field
$hidden = $_POST['_hidden_field'];
if( ! empty( $hidden ) ) {
update_post_meta( $post_id, '_hidden_field', esc_attr( $hidden ) );
}
}
I have tried some woocommerce custom plugin but it didn't solve my requirement as I have 25 above custom filed to be created and plugin seems to be very lengthy process for my work
My output is in picture 2 which I got from coding for not as my requirement
My output
I know you are not interested in plugins, but I highly recommend ACF plugin for custom fields. Check it out, it will save you a lot of time.

How to save WooCommerce checkout custom fields to user meta

I've created the following custom fields for the user meta using the PODS.io Wordpress plugin:
date_of_birth
emergency_contact_name
relation
emergency_phone
I've added these fields to the WooCommerce checkout, under extra information, by using the following code in my theme's functions.php:
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
woocommerce_form_field( 'date_of_birth', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Date of Birth'),
'placeholder' => __('dd/mm/yyyy'),
), $checkout->get_value( 'date_of_birth' ));
woocommerce_form_field( 'emergency_contact_name', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Emergency Contact Name'),
'placeholder' => __('contact name'),
), $checkout->get_value( 'emergency_contact_name' ));
woocommerce_form_field( 'relation', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Emergency Relation'),
'placeholder' => __('wife/husband'),
), $checkout->get_value( 'relation' ));
woocommerce_form_field( 'emergency_phone', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Emergency Phone'),
'placeholder' => __('xxxx xxx xxx / xxxx xxxx'),
), $checkout->get_value( 'emergency_phone' ));
}
Error checking:
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['date_of_birth'] )
wc_add_notice( __( 'Please enter your date of birth' ), 'error' );
if ( ! $_POST['emergency_contact_name'] )
wc_add_notice( __( 'Please enter your Emergency Contact Name' ), 'error' );
if ( ! $_POST['relation'] )
wc_add_notice( __( 'Please enter how your Emergency Contact is related to you' ), 'error' );
if ( ! $_POST['emergency_phone'] )
wc_add_notice( __( 'Please enter the phone number of your Emergency Contact' ), 'error' );
}
(Hopefully) update the user meta upon checkout:
add_action( 'woocommerce_checkout_update_user_meta', 'my_custom_checkout_field_update_user_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( !empty( $_POST['date_of_birth'] ) ) {
$dob = sanitize_text_field( $_POST['date_of_birth'] );
update_user_meta( $current_user->ID, 'date_of_birth', $dob);
}
if ( ! empty( $_POST['emergency_contact_name'] ) ) {
update_user_meta( $user_id, 'emergency_contact_name', sanitize_text_field( $_POST['emergency_contact_name'] ) );
}
if ( ! empty( $_POST['relation'] ) ) {
update_user_meta( $user_id, 'relation', sanitize_text_field( $_POST['relation'] ) );
}
if ( ! empty( $_POST['emergency_phone'] ) ) {
update_user_meta( $user_id, 'emergency_phone', sanitize_text_field( $_POST['emergency_phone'] ) );
}
}
Unfortunately, the user meta custom fields are not updated when I checkout.
I can update the order meta custom fields with the following code:
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['date_of_birth'] ) ) {
update_post_meta( $order_id, 'Date Of Birth', sanitize_text_field( $_POST['date_of_birth'] ) );
}
if ( ! empty( $_POST['emergency_contact_name'] ) ) {
update_post_meta( $order_id, 'Emergency Contact Name', sanitize_text_field( $_POST['emergency_contact_name'] ) );
}
if ( ! empty( $_POST['relation'] ) ) {
update_post_meta( $order_id, 'Emergency Relation', sanitize_text_field( $_POST['relation'] ) );
}
if ( ! empty( $_POST['emergency_phone'] ) ) {
update_post_meta( $order_id, 'Emergency Phone', sanitize_text_field( $_POST['emergency_phone'] ) );
}
}
However, we need the custom fields in the user meta, not the order meta.
Can you see what is wrong with the code that saves custom fields upon checkout to the user meta?
Thanks.
first, you should add your custom fields like this: (use woocommerce_checkout_fields filter)
function reigel_woocommerce_checkout_fields( $checkout_fields = array() ) {
$checkout_fields['order']['date_of_birth'] = array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Date of Birth'),
'placeholder' => __('dd/mm/yyyy'),
'required' => true,
);
return $checkout_fields;
}
add_filter( 'woocommerce_checkout_fields', 'reigel_woocommerce_checkout_fields' );
adding 'required' and setting it to true will have the same effect with how you check if this field is set or not. (your "Error checking")
then in your woocommerce_checkout_update_user_meta, the first parameter is not $order_id but the $customer_id. You should know too that the second parameter is $posted. $posted contains the $_POST[] data. Including your custom fields if you did the code above.
function reigel_woocommerce_checkout_update_user_meta( $customer_id, $posted ) {
if (isset($posted['date_of_birth'])) {
$dob = sanitize_text_field( $posted['date_of_birth'] );
update_user_meta( $customer_id, 'date_of_birth', $dob);
}
}
add_action( 'woocommerce_checkout_update_user_meta', 'reigel_woocommerce_checkout_update_user_meta', 10, 2 );

Resources