I have added the code below. The birthday field is showing in my account page and also in WP admin user page as well but the problem is that the date is not saving.
What I have so far
function iconic_get_account_fields() {
return apply_filters( 'iconic_account_fields', array(
'user_url' => array(
'type' => 'date',
'label' => __( 'My Birth Date', 'iconic' ),
'placeholder' => __( 'Date of Birth', 'iconic' ),
'required' => true,
),
) );
}
/**
* Add fields to registration form and account area.
*/
function iconic_print_user_frontend_fields() {
$fields = iconic_get_account_fields();
foreach ( $fields as $key => $field_args ) {
woocommerce_form_field( $key, $field_args );
}
}
add_action( 'woocommerce_edit_account_form', 'iconic_print_user_frontend_fields', 10 ); // my account
/**
* Add fields to admin area.
*/
function iconic_print_user_admin_fields() {
$fields = iconic_get_account_fields();
?>
<h2><?php _e( 'Additional Information', 'iconic' ); ?></h2>
<table class="form-table" id="iconic-additional-information">
<tbody>
<?php foreach ( $fields as $key => $field_args ) { ?>
<tr>
<th>
<label for="<?php echo $key; ?>"><?php echo $field_args['label']; ?></label>
</th>
<td>
<?php $field_args['label'] = false; ?>
<?php woocommerce_form_field( $key, $field_args ); ?>
</td>
</tr>
<?php } ?>
</tbody>
</table>
<?php
}
add_action( 'show_user_profile', 'iconic_print_user_admin_fields', 30 ); // admin: edit profile
add_action( 'edit_user_profile', 'iconic_print_user_admin_fields', 30 ); // admin: edit other users
I use the code partly from:
The Ultimate Guide to Adding Custom WooCommerce Registration Fields
The following code will add (and save) a custom birthday field to
My account - edit account
Admin user page - profile
// Add field - my account
function action_woocommerce_edit_account_form() {
woocommerce_form_field( 'birthday_field', array(
'type' => 'date',
'label' => __( 'My Birth Date', 'woocommerce' ),
'placeholder' => __( 'Date of Birth', 'woocommerce' ),
'required' => true,
), get_user_meta( get_current_user_id(), 'birthday_field', true ));
}
add_action( 'woocommerce_edit_account_form', 'action_woocommerce_edit_account_form' );
// Validate - my account
function action_woocommerce_save_account_details_errors( $args ){
if ( isset($_POST['birthday_field']) && empty($_POST['birthday_field']) ) {
$args->add( 'error', __( 'Please provide a birth date', 'woocommerce' ) );
}
}
add_action( 'woocommerce_save_account_details_errors','action_woocommerce_save_account_details_errors', 10, 1 );
// Save - my account
function action_woocommerce_save_account_details( $user_id ) {
if( isset($_POST['birthday_field']) && ! empty($_POST['birthday_field']) ) {
update_user_meta( $user_id, 'birthday_field', sanitize_text_field($_POST['birthday_field']) );
}
}
add_action( 'woocommerce_save_account_details', 'action_woocommerce_save_account_details', 10, 1 );
// Add field - admin
function add_user_birtday_field( $user ) {
?>
<h3><?php _e('Birthday','woocommerce' ); ?></h3>
<table class="form-table">
<tr>
<th><label for="birthday_field"><?php _e( 'Date of Birth', 'woocommerce' ); ?></label></th>
<td><input type="date" name="birthday_field" value="<?php echo esc_attr( get_the_author_meta( 'birthday_field', $user->ID )); ?>" class="regular-text" /></td>
</tr>
</table>
<br />
<?php
}
add_action( 'show_user_profile', 'add_user_birtday_field', 10, 1 );
add_action( 'edit_user_profile', 'add_user_birtday_field', 10, 1 );
// Save field - admin
function save_user_birtday_field( $user_id ) {
if( ! empty($_POST['birthday_field']) ) {
update_user_meta( $user_id, 'birthday_field', sanitize_text_field( $_POST['birthday_field'] ) );
}
}
add_action( 'personal_options_update', 'save_user_birtday_field', 10, 1 );
add_action( 'edit_user_profile_update', 'save_user_birtday_field', 10, 1 );
Related
I have added a DOB field to the WooCommerce My account section Account details. The field is a date field (date of birth).
The customer can edit and save. Problem is; the customer can edit and save over and over again.
This is a problem because of the discount that I would like to automatically apply based on the DOB date. If the customer can edit this field more than once; they can potentially get a discount each and every day. For obvious reasons, this cannot happen.
I need help in making the custom field editable ONCE and only once per customer. In wp-admin, admins can edit as they see fit - which is ok.
Here is my full code so far:
add_action( 'woocommerce_edit_account_form', 'dob_on_myaccount_form' );
function dob_on_myaccount_form() {
woocommerce_form_field( 'birthday_field', array (
'type' => 'date',
// how do I set the format to be y-m-d as in Year, Month, Day here
'label' => __('Date of birth', 'woocommerce' ),
'required' => false,
), get_user_meta( get_current_user_id(), 'birthday_field', true ) );
}
add_action( 'woocommerce_save_account_details_errors', 'dob_on_myaccount_form_error', 10, 1 );
function dob_on_myaccount_form_error( $args ) {
if (isset( $_POST['birthday_field'] ) && empty( $_POST['birthday_field'] ) ) {
$args->add('error', __( 'Please provide a date of birth', 'woocommerce' ) );
}
}
add_action( 'woocommerce_save_account_details', 'dob_on_myaccount_form_save', 10, 1 );
function dob_on_myaccount_form_save( $user_id ) {
if ( isset( $_POST['birthday_field'] ) && !empty( $_POST['birthday_field'] ) ) {
update_user_meta( $user_id, 'birthday_field', sanitize_text_field( $_POST['birthday_field'] ) );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'give_birthday_discount', 10, 2 );
function give_birthday_discount( $cart, $date = 'now' ) {
if ( 'now' === $date ) {
$date = date( 'Y-m-d' );
$discount_percentage = 10;
$cart->add_fee( __( 'Birthday Discount', 'woocommerce' ), -( $cart->subtotal * $discount_percentage / 100 ));
}
}
add_action( 'show_user_profile', 'dob_on_admin_profile', 10, 1 );
add_action( 'edit_user_profile', 'dob_on_admin_profile', 10, 1 );
function dob_on_admin_profile( $user ) { ?>
<h3><?php _e('Birthday','woocommerce'); ?></h3>
<table class="form-table">
<tr>
<th><label for="birthday_field"><?php _e('Date of Birth', 'woocommerce'); ?></label></th>
<td><input type="date" name="birthday_field" value="<?php echo esc_attr(get_the_author_meta('birthday_field', $user->ID)); ?>" class="regular-text" /></td>
</tr>
</table>
<br />
<?php
}
add_action( 'personal_options_update', 'dob_on_admin_profile_save', 10, 1 );
add_action( 'edit_user_profile_update', 'dob_on_admin_profile_save', 10, 1 );
function dob_on_admin_profile_save( $user_id ) {
if ( ! empty( $_POST['birthday_field'] ) ) {
update_user_meta( $user_id, 'birthday_field', sanitize_text_field( $_POST['birthday_field'] ) );
}
}
While saving the date field you can save an extra value birthday_field_not_editable
Then you can check if this value is true, if this is the case, the field is no longer editable (readonly = true).
Explanation via comment tags added to the code
// Add field - my account
function dob_on_myaccount_form() {
// Label
$label = __( 'Date of birth', 'woocommerce' );
// Readonly (by default false)
$readonly = false;
// Get current user id
$user_id = get_current_user_id();
// Get value
$not_editable = get_user_meta( $user_id, 'birthday_field_not_editable', true );
// If TRUE
if ( $not_editable ) {
$label = __( 'Date of birth - adjustment is no longer possible', 'woocommerce' );
$readonly = true;
}
// Date field
woocommerce_form_field( 'birthday_field', array (
'type' => 'date',
'label' => $label,
'required' => true,
'custom_attributes' => array( 'readonly' => $readonly ),
), get_user_meta( $user_id, 'birthday_field', true ) );
}
add_action( 'woocommerce_edit_account_form', 'dob_on_myaccount_form', 10, 0 );
// Validate - my account
function dob_on_myaccount_form_error( $args ) {
if ( isset( $_POST['birthday_field'] ) && empty( $_POST['birthday_field'] ) ) {
$args->add('error', __( 'Please provide a date of birth', 'woocommerce' ) );
}
}
add_action( 'woocommerce_save_account_details_errors', 'dob_on_myaccount_form_error', 10, 1 );
// Save - my account
function dob_on_myaccount_form_save( $user_id ) {
if ( isset( $_POST['birthday_field'] ) && ! empty( $_POST['birthday_field'] ) ) {
// Update birthday field
update_user_meta( $user_id, 'birthday_field', sanitize_text_field( $_POST['birthday_field'] ) );
// Update not editable field
update_user_meta( $user_id, 'birthday_field_not_editable', true );
}
}
add_action( 'woocommerce_save_account_details', 'dob_on_myaccount_form_save', 10, 1 );
I have multiple fields in "My Account" page, so, I wanted to add additional field for Date of Birth.
I am using part of Add birthday field to my account and admin user page
The field shows up but it come in the bottom.
I wanted to add DOB field after my 2 existing fields, I tried using 'priority => 20,' but it doesn't work.
// Add field - my account
function action_woocommerce_edit_account_form() {
woocommerce_form_field( 'birthday_field', array(
'type' => 'date',
'label' => __( 'My Birth Date', 'woocommerce' ),
'placeholder' => __( 'Date of Birth', 'woocommerce' ),
'required' => true,
), get_user_meta( get_current_user_id(), 'birthday_field', true ));
}
add_action( 'woocommerce_edit_account_form', 'action_woocommerce_edit_account_form' );
// Validate - my account
function action_woocommerce_save_account_details_errors( $args ){
if ( isset($_POST['birthday_field']) && empty($_POST['birthday_field']) ) {
$args->add( 'error', __( 'Please provide a birth date', 'woocommerce' ) );
}
}
add_action( 'woocommerce_save_account_details_errors','action_woocommerce_save_account_details_errors', 10, 1 );
// Save - my account
function action_woocommerce_save_account_details( $user_id ) {
if( isset($_POST['birthday_field']) && ! empty($_POST['birthday_field']) ) {
update_user_meta( $user_id, 'birthday_field', sanitize_text_field($_POST['birthday_field']) );
}
}
add_action( 'woocommerce_save_account_details', 'action_woocommerce_save_account_details', 10, 1 );
As can be seen in myaccount/form-edit-account.php template file the woocommerce_edit_account_form action hook is executed after the already existing fields are added.
So if you want to add the field between the existing fields you will have to edit the template file
This template can be overridden by copying it to yourtheme/woocommerce/myaccount/form-edit-account.php
You have to delete the code you currently use
Add this code between 2 existing fields (at the place where you want to add the new field) in the myaccount/form-edit-account.php template file
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
<label for="account_birthday"><?php esc_html_e( 'Birth day', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="date" class="woocommerce-Input woocommerce-Input--text input-text" name="account_birthday" id="account_birthday" value="<?php echo get_user_meta( get_current_user_id(), 'account_birthday', true ); ?>"/>
</p>
<div class="clear"></div>
For validation and saving then add the following code to functions.php (
or the way you prefer to add snippets)
// Validate - my account
function action_woocommerce_save_account_details_errors( $args ){
if ( isset( $_POST['account_birthday'] ) && empty( $_POST['account_birthday'] ) ) {
$args->add( 'error', __( 'Please provide a birth date', 'woocommerce' ) );
}
}
add_action( 'woocommerce_save_account_details_errors','action_woocommerce_save_account_details_errors', 10, 1 );
// Save - my account
function action_woocommerce_save_account_details( $user_id ) {
if( isset( $_POST['account_birthday'] ) && ! empty( $_POST['account_birthday'] ) ) {
update_user_meta( $user_id, 'account_birthday', sanitize_text_field( $_POST['account_birthday'] ) );
}
}
add_action( 'woocommerce_save_account_details', 'action_woocommerce_save_account_details', 10, 1 );
I would like print my custom checkout field into all e-mail notification, like in screenshot below.
What works so far
Add the field to the checkout
Process the checkout
Update the order meta with field value
Display field value on the order edit page
My question
How to add the custom checkout field into email order details (as seen in the screenshot)
Here is my code that I have used so far, how can I further adjust it?
/* Add the field to the checkout */
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h3>' . __('Imię i nazwisko osoby obdarowanej') . '</h3>';
woocommerce_form_field( 'my_field_name', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Podaj imię i nazwisko osoby obdarowanej'),
'placeholder' => __(''),
'required' => true,
), $checkout->get_value( 'my_field_name' ));
echo '</div>';
}
/* Process the checkout */
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['my_field_name'] )
wc_add_notice( __( '<strong>Imię i nazwisko osoby obdarowanej</strong> jest wymaganym polem' ), 'error' );
}
/* Update the order meta with field value */
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['my_field_name'] ) ) {
update_post_meta( $order_id, 'My Field', sanitize_text_field( $_POST['my_field_name'] ) );
}
}
/* Display field value on the order edit page */
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Imie i nazwisko obdarowanej').':</strong> ' . get_post_meta( $order->id, 'My Field', true ) . '</p>';
}
Step 1) Change your code to this
/* Add the field to the checkout */
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h3>' . __('Imię i nazwisko osoby obdarowanej') . '</h3>';
woocommerce_form_field( 'my_field_name', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Podaj imię i nazwisko osoby obdarowanej'),
'placeholder' => __(''),
'required' => true,
), $checkout->get_value( 'my_field_name' ));
echo '</div>';
}
/* Process the checkout */
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['my_field_name'] )
wc_add_notice( __( '<strong>Imię i nazwisko osoby obdarowanej</strong> jest wymaganym polem' ), 'error' );
}
/* Update the order meta with field value */
add_action( 'woocommerce_checkout_create_order', 'my_custom_checkout_field_create_order', 10, 2 );
function my_custom_checkout_field_create_order( $order, $data ) {
if ( ! empty( $_POST['my_field_name'] ) ) {
$order->update_meta_data( '_my_field', sanitize_text_field( $_POST['my_field_name'] ) ); // Order meta data
}
}
/* Display field value on the order edit page */
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order) {
// Get meta
$my_field = $order->get_meta( '_my_field' );
echo '<p><strong>'.__('Imie i nazwisko obdarowanej').':</strong> ' . $my_field . '</p>';
}
Step 2) overwrite the following template file
https://github.com/woocommerce/woocommerce/blob/3.8.0/templates/emails/email-order-details.php
This template can be overridden by copying it to
yourtheme/woocommerce/emails/email-order-details.php.
Add the following code under line number 84
$my_field = $order->get_meta( '_my_field' );
if ( isset( $my_field ) ) {
?>
<tr>
<th class="td" scope="row" colspan="2" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php echo 'Imie i nazwisko obdarowanej:'; ?></th>
<td class="td" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php echo $my_field; ?></td>
</tr>
<?php
}
I want to add otp when user register on woo-commerce registration page, i have added custom field for phone number but i am not able to get any sources for otp in word-press i have my own API please if someone can share any resource
for finding it
It will be very helpful ...
function iconic_get_account_fields() {
return apply_filters( 'iconic_account_fields', array(
'user_url' => array(
'type' => 'text',
'label' => __( 'Phone' ),
'placeholder' => __( 'E.g. 9861234567', 'iconic' ),
'required' => true,
),
) );
}
function iconic_print_user_frontend_fields() {
$fields = iconic_get_account_fields();
foreach ( $fields as $key => $field_args ) {
woocommerce_form_field( $key, $field_args );
}
}
add_action( 'woocommerce_register_form', 'iconic_print_user_frontend_fields', 1 );
add_action( 'woocommerce_edit_account_form', 'iconic_print_user_frontend_fields', 10 ); // my account
function iconic_print_user_admin_fields() {
$fields = iconic_get_account_fields();
?>
<h2><?php _e( 'Additional Information', 'iconic' ); ?></h2>
<table class="form-table" id="iconic-additional-information">
<tbody>
<?php foreach ( $fields as $key => $field_args ) { ?>
<tr>
<th>
<label for="<?php echo $key; ?>"><?php echo $field_args['label']; ?></label>
</th>
<td>
<?php $field_args['label'] = false; ?>
<?php woocommerce_form_field( $key, $field_args ); ?>
</td>
</tr>
<?php } ?>
</tbody>
</table>
<?php
}
add_action( 'show_user_profile', 'iconic_print_user_admin_fields', 30 ); // admin: edit profile
add_action( 'edit_user_profile', 'iconic_print_user_admin_fields', 30 );
.
I set up a simple checkbox field in the user account admin interface. Here is how I am displaying/saving it:
function show_free_ground_field( $user ) {
?>
<h3>Free Ground Shipping</h3>
<table class="form-table">
<tr>
<th>Free ground for order > $1000</th>
<td>
<?php
woocommerce_form_field( 'freeGround', array(
'type' => 'checkbox',
'class' => array('input-checkbox'),
'label' => __('Yes'),
), '' );
?>
</td>
</tr>
</table>
<?php
}
add_action( 'show_user_profile', 'show_free_ground_field' );
add_action( 'edit_user_profile', 'show_free_ground_field' );
function save_free_ground_field( $user_id ) {
if ( !current_user_can( 'edit_user', $user_id ) ){
return false;
}
if ( ! empty( $_POST['freeGround'] ) ){
update_usermeta( $user_id, 'freeGround', $_POST['freeGround'] );
}
}
add_action( 'personal_options_update', 'save_free_ground_field' );
add_action( 'edit_user_profile_update', 'save_free_ground_field' );
It displays fine, but if I check it off and re-visit the same user after saving the checkbox is unchecked. How do I fix that?
You should need to get the saved value for this checkbox field in the first function:
add_action( 'show_user_profile', 'show_free_ground_field' );
add_action( 'edit_user_profile', 'show_free_ground_field' );
function show_free_ground_field( $user ) {
?>
<h3>Free Ground Shipping</h3>
<table class="form-table">
<tr>
<th>Free ground for order > $1000</th>
<td>
<?php
$freeGround = get_user_meta( $user->id, 'freeGround', true );
if ( empty( $freeGround ) ) $freeGround = '';
woocommerce_form_field( 'freeGround', array(
'type' => 'checkbox',
'class' => array('input-checkbox'),
'label' => __('Yes'),
), $freeGround );
?>
</td>
</tr>
</table>
<?php
}
This should work now