Required custom field woocommerce customer profile - php

I want to add some fields to customer profile and I have added following this question
This works good if my fields aren't required, but how can I do them required and show an error when customer doesn't fill them?
With this code I can add an error but it appears after another ok message and redirect to "my account" page:
add_action('woocommerce_edit_account_form', 'add_favorite_color_to_edit_account_form');
function add_favorite_color_to_edit_account_form()
{
$user = wp_get_current_user();
?>
<p class="woocommerce-form-row woocommerce-form-row--first form-row form-row-first">
<label for="favorite_color"><?php _e('Favorite color', 'woocommerce'); ?>
<input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="favorite_color" id="favorite_color" value="<?php echo esc_attr($user->favorite_color); ?>" />
</p>
<?php
}
add_action('woocommerce_save_account_details', 'save_favorite_color_account_details', 12, 1);
function save_favorite_color_account_details($user_id)
{
$fav_color = $_POST['favorite_color'];
if (empty($fav_color)) {
wc_add_notice(__('Fav color is required!', 'xxxxx'), 'error');
} else {
update_user_meta($user_id, 'favorite_color', sanitize_text_field($_POST['favorite_color']));
}
}

Related

How to create a password and confirm password on register page on WooCommerce

I am learning WooCommerce development. I am on the register page and after entering the email and click on the button the I am getting the password on email.
Now my issue is, I don't want an email for a password. I have created the register page with the password and confirm the password field.
I want can enter their own there instead of getting the email on this password.
function woocom_extra_register_fields() {
?>
<p class="form-row form-row-wide mb-4">
<label for="reg_billing_password" class="text-uppercase"><?php _e('Password', 'woocommerce' ); ?><span class="required">*</span></label><input type="password" class="input-text form-control" name="billing_password" id="reg_billing_password" value="<?php if ( ! empty( $_POST['billing_password'] ) ) esc_attr_e( $_POST['billing_password'] ); ?>" placeholder="Password" />
</p>
<p class="form-row form-row-wide">
<label for="reg_billing_confirmpassword" class="text-uppercase"><?php _e('Confirm Password', 'woocommerce'); ?><span class="required">*</span></label><input type="password" class="input-text form-control" name="billing_confirmpassword" id="reg_billing_confirmpassword" value="<?php if ( ! empty( $_POST['billing_confirmpassword'] ) ) esc_attr_e( $_POST['billing_confirmpassword'] ); ?>" placeholder="Confirm Password"/>
</p>
<?php
}
add_action('woocommerce_register_form', 'woocom_extra_register_fields');
function woocom_validate_extra_register_fields( $username, $email, $validation_errors )
{
if (isset($_POST['billing_password']) && empty($_POST['billing_password']) )
{
$validation_errors->add('billing_password_error', __('Password is required!', 'woocommerce'));
}
if (isset($_POST['billing_confirmpassword']) && empty($_POST['billing_confirmpassword']) )
{
$validation_errors->add('billing_confirmpassword_error', __('Confirm password is required!', 'woocommerce'));
}
return $validation_errors;
}
add_action('woocommerce_register_post', 'woocom_validate_extra_register_fields', 10, 3);
function woocom_save_extra_register_fields($customer_id) {
if (isset($_POST['billing_password']))
{
update_user_meta($customer_id, 'billing_password', sanitize_text_field($_POST['billing_password']));
}
if (isset($_POST['billing_confirmpassword']))
{
update_user_meta($customer_id, 'billing_confirmpassword', sanitize_text_field($_POST['billing_confirmpassword']));
}
}
add_action('woocommerce_created_customer', 'woocom_save_extra_register_fields');
Would you help me out with this issue?
To disable the automatic generation of the password when a new account is created, you must disable the When creating an account, automatically generate an account password option from the WooCommerce admin page.
To do this, go to WooCommerce > Settings > Accounts & Privacy:
You can find more information here: WooCommerce - Accounts & Privacy Settings.

Customize WooCommerce login form user fields

I would like to include a placeholder in the woocommerce login form.
Looking at this for a starting point:
woocommerce add placeholder text to edit account form:
add_filter( 'woocommerce_form_field_args', 'custom_form_field_args', 10, 3 );
function custom_form_field_args( $args, $key, $value ) {
if ( $args['id'] == 'username' ) {
$args['placeholder'] = 'My placeholder text';
}
return $args;
};
Not working as it is. Open to any suggestions.
As the login fields are hard coded in myaccount/form-login.php template file, the only way to add placeholder(s) to those fields, requires overriding the related template via the active child theme (or active theme)
Once you have copied the myaccount/form-login.php template file located in WooCommerce plugin under the "templates" folder to (as explained on the template):
<?php
/**
* Login Form
*
* This template can be overridden by copying it to yourtheme/woocommerce/myaccount/form-login.php.
Open/Edit form-login.php copied file, and add to all desired <input> html tags:
placeholder="placeholder text"
Like for example replacing from line 38 to 45 with the following:
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
<label for="username"><?php esc_html_e( 'Username or email address', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="username" id="username" placeholder="<?ph esc_html_e("Here type your Username (or email address)"); ?>" autocomplete="username" value="<?php echo ( ! empty( $_POST['username'] ) ) ? esc_attr( wp_unslash( $_POST['username'] ) ) : ''; ?>" /><?php // #codingStandardsIgnoreLine ?>
</p>
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
<label for="password"><?php esc_html_e( 'Password', 'woocommerce' ); ?> <span class="required">*</span></label>
<input class="woocommerce-Input woocommerce-Input--text input-text" type="password" name="password" id="password" placeholder="<?ph esc_html_e(""Here type your password"); ?>" autocomplete="current-password" />
</p>
Then save… You will get something like:
Related threads:
WooCommerce condition for is_account_page(), but only the login portion
Add a field to Woocommerce registration form and in admin edit user
Sync additional Billing registration fields with default Wordpress fields in WooCommerce

Add a mobile phone field on My account > edit account in Woocommerce

my question:
How to add mobile phone field in Woocommerce my-account/edit-account/ page
(Related template: form-edit-account.php file)
Like in the following answer thread:
Saving the value of a custom field phone number in WooCommerce My account > Account details
But this answer code is incomplete as there is some missing hooked functions. Any help is appreciated to get something complete, meaning the field display.
You have 3 options to display a custom mobile phone field on My account > Edit account page:
1) As the first field using woocommerce_edit_account_form_start action hook (see below).
2) After existing fields using woocommerce_edit_account_form action hook:
// Display the mobile phone field
// add_action( 'woocommerce_edit_account_form_start', 'add_billing_mobile_phone_to_edit_account_form' ); // At start
add_action( 'woocommerce_edit_account_form', 'add_billing_mobile_phone_to_edit_account_form' ); // After existing fields
function add_billing_mobile_phone_to_edit_account_form() {
$user = wp_get_current_user();
?>
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
<label for="billing_mobile_phone"><?php _e( 'Mobile phone', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="text" class="woocommerce-Input woocommerce-Input--phone input-text" name="billing_mobile_phone" id="billing_mobile_phone" value="<?php echo esc_attr( $user->billing_mobile_phone ); ?>" />
</p>
<?php
}
// Check and validate the mobile phone
add_action( 'woocommerce_save_account_details_errors','billing_mobile_phone_field_validation', 20, 1 );
function billing_mobile_phone_field_validation( $args ){
if ( isset($_POST['billing_mobile_phone']) && empty($_POST['billing_mobile_phone']) )
$args->add( 'error', __( 'Please fill in your Mobile phone', 'woocommerce' ),'');
}
// Save the mobile phone value to user data
add_action( 'woocommerce_save_account_details', 'my_account_saving_billing_mobile_phone', 20, 1 );
function my_account_saving_billing_mobile_phone( $user_id ) {
if( isset($_POST['billing_mobile_phone']) && ! empty($_POST['billing_mobile_phone']) )
update_user_meta( $user_id, 'billing_mobile_phone', sanitize_text_field($_POST['billing_mobile_phone']) );
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
3) In a specific location, overriding myaccount/form-edit-account.php template file via the theme as explained on this documentation. and on this answer thread…
In this case you will need to add the following html code in the template (like in this answer thread):
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
<label for="billing_mobile_phone"><?php _e( 'Mobile phone', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="text" class="woocommerce-Input woocommerce-Input--phone input-text" name="billing_mobile_phone" id="billing_mobile_phone" value="<?php echo esc_attr( $user->billing_mobile_phone ); ?>" />
</p>
In this last case, you will need to add in your theme's function.php file the 2 last hooked functions from section 2 (validation and saving).

Make My account edit-account fields readonly in Woocommerce

I need to make woocommerce my-account/edit-account/ page email, or last name or another field. One field or two fields, ReadOnly.
My solution is edit form-edit-account.php file in plugins/woocommerce/templates/myaccount folder and edit form-edit-account.php file and add readonly to end of tags and work correctly. For example:
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
<label for="account_email"><?php esc_html_e( 'Email address', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="email" class="woocommerce-Input woocommerce-Input--email input-text" name="account_email" id="account_email" autocomplete="email" value="<?php echo esc_attr( $user->user_email ); ?>" readonly />
</p>
But I need make this change only from function.php file. Is this possible? I need code for functions.php file.
You could also use jQuery instead (here for the "billing_mobile_phone" field):
add_action( 'wp_footer' , 'make_phone_field_readonly' );
function make_phone_field_readonly(){
// Only for account fields
if( is_account_page() ): ?>
<script type='text/javascript'>
jQuery(function($){
$('form.edit-account input#billing_mobile_phone').prop('readonly', true );
});
</script>
<?php endif;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Or as in your penultimate question, you will use the hooked function adding readonly attribute to your additional fields:
// Display the mobile phone field
// add_action( 'woocommerce_edit_account_form_start', 'add_billing_mobile_phone_to_edit_account_form' ); // At start
add_action( 'woocommerce_edit_account_form', 'add_billing_mobile_phone_to_edit_account_form' ); // After existing fields
function add_billing_mobile_phone_to_edit_account_form() {
$user = wp_get_current_user();
?>
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
<label for="billing_mobile_phone"><?php _e( 'Mobile phone', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="text" class="woocommerce-Input woocommerce-Input--phone input-text" name="billing_mobile_phone" id="billing_mobile_phone" value="<?php echo esc_attr( $user->billing_mobile_phone ); ?>" readonly />
</p>
<?php
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
So at all you have 3 alternatives:
Add the readonly attribute with jQuery (may be the best way)
Overriding the template via the theme (adding the readonly attribute)
Add custom account fields with the read only attribute

Add Custom registration fields in WooCommerce and phone field validation issue

Similar questions have been asked before and I tried all the solutions but for some reason they won't work for me.
I have a mini Woocommerce registration field included in the footer of my site so that people can register easily. The phone field is required but I want to set a minimum length to it to reduce the number of people entering fake numbers.
I have the following codes added to my functions.php, (I'm including all the notifications to the form so that you can understand better) the placeholder and everything works but I can't get the minimum length (set using "pattern" custom attribute) to work.
If anyone can help me fix it, it'd be very much appreciated.
This form is included in the footer of my web site: wondercatspopup.com
The code I've added is:
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
function custom_override_checkout_fields( $fields )
{
$fields['billing']['billing_phone']['custom_attributes'] = array( "pattern" => ".{10,10}" );
return $fields;
}
And this is the rest of the functions.php:
/**
* To add WooCommerce registration form custom fields.
*/
function text_domain_woo_reg_form_fields() {
?>
<div class="formumuz" style="display:flex;"> <p class="form-row form-row-first">
<label style="display:none!important;" for="billing_first_name"><?php _e('First name', 'woocommerce'); ?><span class="required">*</span></label>
<input style="width: 130px;
display: inline-block; margin-right:1px;" type="text" class="woocommerce-Input woocommerce-Input--text input-text placeholder" placeholder="İsim / Name *" type="text" class="input-text" name="billing_first_name" id="billing_first_name" value="<?php if (!empty($_POST['billing_first_name'])) esc_attr_e($_POST['billing_first_name']); ?>" />
<label style="display:none!important;" for="billing_last_name"><?php _e('Last name', 'woocommerce'); ?><span class="required">*</span></label>
<input style="width: 130px;
display: inline-block; margin-left:1px;" type="text" class="woocommerce-Input woocommerce-Input--text input-text placeholder" placeholder="Soyisim / Surname *" type="text" class="input-text" name="billing_last_name" id="billing_last_name" value="<?php if (!empty($_POST['billing_last_name'])) esc_attr_e($_POST['billing_last_name']); ?>" />
</p></div>
<p style="margin-bottom: 0px; margin-top: 10px;" class="form-row form-row-wide">
<label style="display:none!important;" for="reg_billing_phone"><?php _e( 'Phone', 'woocommerce' ); ?></label>
<input style="width:254px!important;" type="text" class="woocommerce-Input woocommerce-Input--text input-text placeholder" placeholder="Cep Telefonu / Mobile *" value="+905" name="billing_phone" id="reg_billing_phone" value="<?php esc_attr_e( $_POST['billing_phone'] ); ?>" /> *
</p><br>
<div class="clear"></div>
<?php
}
add_action('woocommerce_register_form_start', 'text_domain_woo_reg_form_fields');
/**
* To validate WooCommerce registration form custom fields.
*/
function text_domain_woo_validate_reg_form_fields($username, $email, $validation_errors) {
if (isset($_POST['billing_first_name']) && empty($_POST['billing_first_name'])) {
$validation_errors->add('billing_first_name_error', __('İsim alanı zorunludur! / Name field is required!', 'woocommerce'));
}
if (isset($_POST['billing_last_name']) && empty($_POST['billing_last_name'])) {
$validation_errors->add('billing_last_name_error', __('Soyisim alanı zorunludur! / Surname field is required!', 'woocommerce'));
}
if (isset($_POST['billing_phone']) && empty($_POST['billing_phone'])) {
$validation_errors->add('billing_phone_error', __('Telefon alanı zorunludur! / Phone field is required!', 'woocommerce'));
}
return $validation_errors;
}
add_action('woocommerce_register_post', 'text_domain_woo_validate_reg_form_fields', 10, 3);
/**
* To save WooCommerce registration form custom fields.
*/
function text_domain_woo_save_reg_form_fields($customer_id) {
//First name field
if (isset($_POST['billing_first_name'])) {
update_user_meta($customer_id, 'first_name', sanitize_text_field($_POST['billing_first_name']));
update_user_meta($customer_id, 'billing_first_name', sanitize_text_field($_POST['billing_first_name']));
}
//Last name field
if (isset($_POST['billing_last_name'])) {
update_user_meta($customer_id, 'last_name', sanitize_text_field($_POST['billing_last_name']));
update_user_meta($customer_id, 'billing_last_name', sanitize_text_field($_POST['billing_last_name']));
}
//Phone field
if (isset($_POST['billing_phone'])) {
update_user_meta($customer_id, 'phone', sanitize_text_field($_POST['billing_phone']));
update_user_meta($customer_id, 'billing_phone', sanitize_text_field($_POST['billing_phone']));
}
}
Note: Your special registration form located in the footer is something different than WooCommerce checkout fields.
In your code the hook for your validating function text_domain_woo_validate_reg_form_fields() is just missing. There is also some small errors (corrected)…
The best place to check the submitted data is your validation function and you should also need to add another one for checkout too (instead of using a custom pattern for checkout phone field, that is used to format data).
So all your related code should be:
## --- FOR CHECKOUT --- ##
// Checkout billing phone validation (Checking length)
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
if ( $_POST['billing_phone'] && strlen($_POST['billing_phone']) < 10 )
wc_add_notice( __('Please type a correct phone number…', 'woocommerce'), 'error' );
}
## --- FOR CUSTOM REGISTRATION FORM --- ##
// Add custom fields to registration form.
add_action('woocommerce_register_form_start', 'text_domain_woo_reg_form_fields');
function text_domain_woo_reg_form_fields() {
?>
<div class="formumuz" style="display:flex;">
<p class="form-row form-row-first">
<label style="display:none!important;" for="billing_first_name"><?php _e('First name', 'woocommerce'); ?><span class="required">*</span></label>
<input style="width: 130px; display: inline-block; margin-right:1px;" type="text" class="woocommerce-Input woocommerce-Input--text input-text placeholder" placeholder="İsim / Name *" type="text" class="input-text" name="billing_first_name" id="billing_first_name" value="<?php if (!empty($_POST['billing_first_name'])) esc_attr_e($_POST['billing_first_name']); ?>" />
</p>
<p class="form-row form-row-last">
<label style="display:none!important;" for="billing_last_name"><?php _e('Last name', 'woocommerce'); ?><span class="required">*</span></label>
<input style="width: 130px; display: inline-block; margin-left:1px;" type="text" class="woocommerce-Input woocommerce-Input--text input-text placeholder" placeholder="Soyisim / Surname *" type="text" class="input-text" name="billing_last_name" id="billing_last_name" value="<?php if (!empty($_POST['billing_last_name'])) esc_attr_e($_POST['billing_last_name']); ?>" />
</p>
</div>
<p style="margin-bottom: 0px; margin-top: 10px;" class="form-row form-row-wide">
<label style="display:none!important;" for="reg_billing_phone"><?php _e( 'Phone', 'woocommerce' ); ?></label>
<!-- "You can’t have 2 times the value attribute and you can use "tel" type … (to be removed)" -->
<input style="width:254px!important;" type="tel" class="woocommerce-Input woocommerce-Input--text input-text placeholder" placeholder="Cep Telefonu / Mobile *" name="billing_phone" id="reg_billing_phone" value="<?php esc_attr_e( $_POST['billing_phone'] ); ?>" /> *
</p><br>
<div class="clear"></div>
<?php
}
// Checking & validation of custom fields in registration form.
add_action('woocommerce_register_post', 'text_domain_woo_validate_reg_form_fields', 10, 3);
function text_domain_woo_validate_reg_form_fields( $username, $email, $validation_errors ) {
if (isset($_POST['billing_first_name']) && empty($_POST['billing_first_name'])) {
$validation_errors->add('billing_first_name_error', __('İsim alanı zorunludur! / Name field is required!', 'woocommerce'));
}
if (isset($_POST['billing_last_name']) && empty($_POST['billing_last_name'])) {
$validation_errors->add('billing_last_name_error', __('Soyisim alanı zorunludur! / Surname field is required!', 'woocommerce'));
}
if (isset($_POST['billing_phone']) && empty($_POST['billing_phone'])) {
$validation_errors->add('billing_phone_error', __('Telefon alanı zorunludur! / Phone field is required!', 'woocommerce'));
}
// ==> CHECKING PHONE LENGTH (10 character minimal) <==
if (isset($_POST['billing_phone']) && strlen($_POST['billing_phone']) < 10 ) {
$validation_errors->add('billing_phone_error', __('Please type a correct phone number…', 'woocommerce'));
}
return $validation_errors;
}
// Add custom fields to registration form.
add_action( 'woocommerce_created_customer', 'custom_save_extra_register_fields' ); // <==== Missing
function custom_save_extra_register_fields($customer_id) {
//First name field
if (isset($_POST['billing_first_name'])) {
update_user_meta($customer_id, 'first_name', sanitize_text_field($_POST['billing_first_name']));
update_user_meta($customer_id, 'billing_first_name', sanitize_text_field($_POST['billing_first_name']));
}
//Last name field
if (isset($_POST['billing_last_name'])) {
update_user_meta($customer_id, 'last_name', sanitize_text_field($_POST['billing_last_name']));
update_user_meta($customer_id, 'billing_last_name', sanitize_text_field($_POST['billing_last_name']));
}
//Phone field
if (isset($_POST['billing_phone'])) {
update_user_meta($customer_id, 'phone', sanitize_text_field($_POST['billing_phone']));
update_user_meta($customer_id, 'billing_phone', sanitize_text_field($_POST['billing_phone']));
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works
Each time the phone number minimal length will be checked and display this alert (if needed):

Categories