Woocommerce save_account_details - wordpress

In woocommerce form-edit-account.php, i have the following but would only like to retain the Password and Confirm new password fields. I deleted all fields except Password and Confirm new password field but there is a validator that prompts me to fill up First Name, Last Name, Email address fields. How do i disable the validator for that? Really need help on this. Thanks in advance.
<?php
/**
* Edit account form
*
* #author WooThemes
* #package WooCommerce/Templates
* #version 1.6.4
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
global $woocommerce;
?>
<?php wc_print_notices(); ?>
<form action="" method="post">
<p class="form-row form-row-first">
<label for="account_first_name"><?php _e( 'First name', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="text" class="input-text" name="account_first_name" id="account_first_name" value="<?php esc_attr_e( $user->first_name ); ?>" />
</p>
<p class="form-row form-row-last">
<label for="account_last_name"><?php _e( 'Last name', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="text" class="input-text" name="account_last_name" id="account_last_name" value="<?php esc_attr_e( $user->last_name ); ?>" />
</p>
<p class="form-row form-row-wide">
<label for="account_email"><?php _e( 'Email address', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="email" class="input-text" name="account_email" id="account_email" value="<?php esc_attr_e( $user->user_email ); ?>" />
</p>
<p class="form-row form-row-first">
<label for="password_1"><?php _e( 'Password (leave blank to leave unchanged)', 'woocommerce' ); ?></label>
<input type="password" class="input-text" name="password_1" id="password_1" />
</p>
<p class="form-row form-row-last">
<label for="password_2"><?php _e( 'Confirm new password', 'woocommerce' ); ?></label>
<input type="password" class="input-text" name="password_2" id="password_2" />
</p>
<div class="clear"></div>
<p><input type="submit" class="button" name="save_account_details" value="<?php _e( 'Save changes', 'woocommerce' ); ?>" /></p>
<?php wp_nonce_field( 'save_account_details' ); ?>
<input type="hidden" name="action" value="save_account_details" />
</form>

Well, I do that using this:
// Hook in
add_filter( 'woocommerce_default_address_fields' , 'custom_override_default_address_fields' );
function custom_override_default_address_fields( $fields ) {
unset($fields['first_name']);
return $fields;
}
It will remove the "First Name" field from both, billing and shipping address.

After some quick research, the solution to exactly your problem, and also resently my problem.
Just add this to functions.php
add_filter( 'woocommerce_save_account_details_required_fields','custom_woocommerce_save_account_details_required_fields' );
function custom_woocommerce_save_account_details_required_fields( $required_fields ) {
unset($required_fields["account_first_name"]);
unset($required_fields["account_last_name"]);
return $required_fields;
}
It will remove the First Name field and Last Name field from the condition of required fields. Of course you can do that with all of your required inputs.

You can remove these validation manually.
Woocomaerce->includes->class-wc-form-handler.php
find function
save_account_details()
edit this function or you can remove validation form here.

Related

Change password without entering current one on My account > edit account in WooCommerce

I would like to disable the "current password" field when a user tries to change their password. Often users have difficulty with passwords, when forgotten it is not possible to ask for the current password.
The user edit form is this: https://woocommerce.github.io/code-reference/files/woocommerce-templates-myaccount-form-edit-account.html
I tried deleting the content relating to line 50 to 53 which would be the current password field, but this is not enough, the current password is still needed.
Then I thought about working around the required attribute but it doesn't exist in the form, apparently wordpress asks for validation in another way.
How could the problem be solved?
Template name: form-edit-account.php
<?php
/**
* Edit account form
*
* This template can be overridden by copying it to yourtheme/woocommerce/myaccount/form-edit-account.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* #see https://docs.woocommerce.com/document/template-structure/
* #package WooCommerce\Templates
* #version 3.5.0
*/
defined( 'ABSPATH' ) || exit;
do_action( 'woocommerce_before_edit_account_form' ); ?>
<form class="woocommerce-EditAccountForm edit-account" action="" method="post" <?php do_action( 'woocommerce_edit_account_form_tag' ); ?> >
<?php do_action( 'woocommerce_edit_account_form_start' ); ?>
<p class="woocommerce-form-row woocommerce-form-row--first form-row form-row-first">
<label for="account_first_name"><?php esc_html_e( 'First name', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="account_first_name" id="account_first_name" autocomplete="given-name" value="<?php echo esc_attr( $user->first_name ); ?>" />
</p>
<p class="woocommerce-form-row woocommerce-form-row--last form-row form-row-last">
<label for="account_last_name"><?php esc_html_e( 'Last name', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="account_last_name" id="account_last_name" autocomplete="family-name" value="<?php echo esc_attr( $user->last_name ); ?>" />
</p>
<div class="clear"></div>
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
<label for="account_display_name"><?php esc_html_e( 'Display name', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="account_display_name" id="account_display_name" value="<?php echo esc_attr( $user->display_name ); ?>" /> <span><em><?php esc_html_e( 'This will be how your name will be displayed in the account section and in reviews', 'woocommerce' ); ?></em></span>
</p>
<div class="clear"></div>
<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 ); ?>" />
</p>
<fieldset>
<legend><?php esc_html_e( 'Password change', 'woocommerce' ); ?></legend>
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
<label for="password_current"><?php esc_html_e( 'Current password (leave blank to leave unchanged)', 'woocommerce' ); ?></label>
<input type="password" class="woocommerce-Input woocommerce-Input--password input-text" name="password_current" id="password_current" autocomplete="off" />
</p>
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
<label for="password_1"><?php esc_html_e( 'New password (leave blank to leave unchanged)', 'woocommerce' ); ?></label>
<input type="password" class="woocommerce-Input woocommerce-Input--password input-text" name="password_1" id="password_1" autocomplete="off" />
</p>
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
<label for="password_2"><?php esc_html_e( 'Confirm new password', 'woocommerce' ); ?></label>
<input type="password" class="woocommerce-Input woocommerce-Input--password input-text" name="password_2" id="password_2" autocomplete="off" />
</p>
</fieldset>
<div class="clear"></div>
<?php do_action( 'woocommerce_edit_account_form' ); ?>
<p>
<?php wp_nonce_field( 'save_account_details', 'save-account-details-nonce' ); ?>
<button type="submit" class="woocommerce-Button button" name="save_account_details" value="<?php esc_attr_e( 'Save changes', 'woocommerce' ); ?>"><?php esc_html_e( 'Save changes', 'woocommerce' ); ?></button>
<input type="hidden" name="action" value="save_account_details" />
</p>
<?php do_action( 'woocommerce_edit_account_form_end' ); ?>
</form>
<?php do_action( 'woocommerce_after_edit_account_form' ); ?>
Note: as indicated it is better not to make any changes as this will make the application less secure. However, to answer your question:
While the output from the current password field can be easily modified by overwriting the template file, the validation is hard coded and can be found in the /includes/class-wc-form-handler.php file.
To bypass the validation we have to pass 2 error messages, namely:
Please enter your current password
Your current password is incorrect
To get around this, we are not going to use the real current password, but we are going to create/add extra custom data, and on that basis allow the user to change his password.
1) To bypass the first notice you will have to overwrite the /myaccount/form-edit-account.php template file.
Replace line 50 - 53 #version 3.5.0
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
<label for="password_current"><?php esc_html_e( 'Current password (leave blank to leave unchanged)', 'woocommerce' ); ?></label>
<input type="password" class="woocommerce-Input woocommerce-Input--password input-text" name="password_current" id="password_current" autocomplete="off" />
</p>
With
<?php
// Get userID
$user_id = $user->ID;
// Generate salt
$salt = md5( openssl_random_pseudo_bytes( 32, $cstrong ) . wp_generate_password( 32, true, true ) );
$enc = $user_id . '::' . crypt( $user_id, $salt );
// NOT empty
if ( ! empty ( $enc ) ) {
update_user_meta( $user_id, '_enc', $enc );
}
// Encodes data with MIME base64
$value = base64_encode( $enc );
// NOT empty
if ( ! empty ( $value ) ) {
?>
<input type="hidden" name="password_current" id="password_current" value="<?php echo $value; ?>" />
<?php
} else {
?>
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
<label for="password_current"><?php esc_html_e( 'Current password (leave blank to leave unchanged)', 'woocommerce' ); ?></label>
<input type="password" class="woocommerce-Input woocommerce-Input--password input-text" name="password_current" id="password_current" autocomplete="off" />
</p>
<?php
}
?>
This will replace the current password field with a hidden input field with a specified value. This value is based on the current userID and a salt, which is then saved as user_meta when the page is requested.
2) To bypass the second notification, you can use the check_password() WordPress filter hook
/**
* Filters whether the plaintext password matches the encrypted password.
*
* #since 2.5.0
*
* #param bool $check Whether the passwords match.
* #param string $password The plaintext password.
* #param string $hash The hashed password.
* #param string|int $user_id User ID. Can be empty.
*/
function filter_check_password( $check, $password, $hash, $user_id ) {
// Only for WooCommerce edit-account endpoint
if ( ! is_wc_endpoint_url( 'edit-account' ) ) return $check;
// Get meta
$enc = get_user_meta( $user_id, '_enc', true );
// NOT empty
if ( ! empty ( $enc ) ) {
// Get parts
$parts = explode( '::', base64_decode( $password ) );
// Compare user ID and data
if ( $parts[0] == $user_id && str_contains( $enc, $parts[1] ) ) {
$check = true;
}
}
return $check;
}
add_filter( 'check_password', 'filter_check_password', 10, 4 );
This will ensure that instead of using the real current password (which is encrypted), our custom user_meta is used. When it matches, we allow to change the password

How to change the added phone value in edit-account template form?

I needed to add fields 'firstname','lastname' and 'phone' to the register woocommerce form.
I've found that decision.
function wooc_extra_register_fields() {?>
<div class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide form-group">
<input type="text" name="billing_first_name" id="reg_billing_first_name" value="<?php if ( ! empty( $_POST['billing_first_name'] ) ) esc_attr_e( $_POST['billing_first_name'] ); ?>" class="woocommerce-Input woocommerce-Input--text input-text form-control" size="25" placeholder="<?php _e( 'First Name', 'mydomain' ) ?>" />
</div>
<div class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide form-group">
<input type="text" name="billing_last_name" id="reg_billing_last_name" value="<?php if ( ! empty( $_POST['billing_last_name'] ) ) esc_attr_e( $_POST['billing_last_name'] ); ?>" placeholder="<?php _e( 'Last Name', 'mydomain' ) ?>" class="woocommerce-Input woocommerce-Input--text input-text form-control" size="25" />
</div>
<div class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide form-group">
<input type="text" name="billing_phone" id="reg_billing_phone" placeholder="<?php _e( 'Phone', 'woocommerce' ); ?>" value="<?php esc_attr_e( $_POST['billing_phone'] ); ?>" class="woocommerce-Input woocommerce-Input--text input-text form-control" size="25" />
</div>
<?php
}
add_action( 'woocommerce_register_form_start', 'wooc_extra_register_fields' );
/**
* register fields Validating.
*/
function wooc_validate_extra_register_fields( $username, $email, $validation_errors ) {
if ( isset( $_POST['billing_first_name'] ) && empty( $_POST['billing_first_name'] ) ) {
$validation_errors->add( 'billing_first_name_error', __( '<strong>Error</strong>: First name is required!', 'woocommerce' ) );
}
if ( isset( $_POST['billing_last_name'] ) && empty( $_POST['billing_last_name'] ) ) {
$validation_errors->add( 'billing_last_name_error', __( '<strong>Error</strong>: Last name is required!.', 'woocommerce' ) );
}
if ( isset( $_POST['billing_phone'] ) && empty( $_POST['billing_phone'] ) ) {
$validation_errors->add( 'billing_phone_error', __( '<strong>Error</strong>: Phone is required!.', 'woocommerce' ) );
}
return $validation_errors;
}
add_action( 'woocommerce_register_post', 'wooc_validate_extra_register_fields', 10, 3 );
/**
* Below code save extra fields.
*/
function wooc_save_extra_register_fields( $customer_id ) {
if ( isset( $_POST['billing_phone'] ) ) {
// Phone input filed which is used in WooCommerce
update_user_meta( $customer_id, 'billing_phone', sanitize_text_field( $_POST['billing_phone'] ) );
}
if ( isset( $_POST['billing_first_name'] ) ) {
//First name field which is by default
update_user_meta( $customer_id, 'first_name', sanitize_text_field( $_POST['billing_first_name'] ) );
// First name field which is used in WooCommerce
update_user_meta( $customer_id, 'billing_first_name', sanitize_text_field( $_POST['billing_first_name'] ) );
}
if ( isset( $_POST['billing_last_name'] ) ) {
// Last name field which is by default
update_user_meta( $customer_id, 'last_name', sanitize_text_field( $_POST['billing_last_name'] ) );
// Last name field which is used in WooCommerce
update_user_meta( $customer_id, 'billing_last_name', sanitize_text_field( $_POST['billing_last_name'] ) ); }
}
add_action( 'woocommerce_created_customer', 'wooc_save_extra_register_fields' );
In myaccount form-edit-account.php template it looks like that
<form class="woocommerce-EditAccountForm edit-account" action="" method="post" <?php do_action( 'woocommerce_edit_account_form_tag' ); ?> >
<?php do_action( 'woocommerce_edit_account_form_start' ); ?>
<p class="woocommerce-form-row woocommerce-form-row--first form-row form-row-first page-inside-p">
<input type="text" class="woocommerce-Input woocommerce-Input--text input-text form-control" name="account_first_name" id="account_first_name" autocomplete="given-name" value="<?php echo esc_attr( $user->first_name ); ?>" placeholder="<?php esc_html_e( 'First name', 'woocommerce' ); ?>" />
</p>
<p class="woocommerce-form-row woocommerce-form-row--last form-row form-row-last page-inside-p">
<input type="text" class="woocommerce-Input woocommerce-Input--text input-text form-control" name="account_last_name" id="account_last_name" autocomplete="family-name" value="<?php echo esc_attr( $user->last_name ); ?>" placeholder="<?php esc_html_e( 'Last name', 'woocommerce' ); ?>" />
</p>
<div class="clear"></div>
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide page-inside-p">
<input type="text" class="woocommerce-Input woocommerce-Input--text input-text form-control" name="account_display_name" id="account_display_name" value="<?php echo esc_attr( $user->display_name ); ?>" placeholder="<?php esc_html_e( 'Display name', 'woocommerce' ); ?>" />
</p>
<div class="clear"></div>
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide mb-20 page-inside-p">
<input type="email" class="woocommerce-Input woocommerce-Input--email input-text form-control" name="account_email" id="account_email" autocomplete="email" value="<?php echo esc_attr( $user->user_email ); ?>" placeholder="<?php esc_html_e( 'Email address', 'woocommerce' ); ?>" />
</p>
<div class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide form-group">
<input type="text" name="billing_phone" id="reg_billing_phone" placeholder="<?php _e( 'Phone', 'woocommerce' ); ?>" value="<?php esc_attr_e( $_POST['billing_phone'] ); ?>" class="woocommerce-Input woocommerce-Input--text input-text form-control" size="25" />
</div>....etc
The first name and the last name are can be changed correctly, but I don't see the value of a phone number in that page and can't update it to save. What's the right way to do it? I copied the same phone field as in the register form, but it seems that's a wrong way. How to display and change it correctly?
The first part of your code is for updating user fields. You have "name" attributes in your HTML Input tags. Submitting these values are achieved by these names.
After submission, if those fields are validated then update_user_meta function is used to update database records for this user with new values of given fields. So, the $_POST['billing_phone'] is used for this purpose and you can not retrieve data by using it.
The problem is in your "myaccount form-edit-account.php". As you can see, all other correct parts gets values from user object. Like value="<?php echo esc_attr( $user->first_name ); ?>" gets the current user's first name.
For phone number, you should use billing_phone field since you are using update_user_meta method for this field and you can retrive this updated data by using get_user_meta method.
So, replacing value="<?php esc_attr_e( $_POST['billing_phone'] ); ?>" with correct assignment value="<?php echo esc_attr( get_user_meta($user->id,'billing_phone',true) ); ?>" will solve your problem.
Also, to update this phone number (billing_phone) field from my account page you may check this answer which is directly shows the solution: Add a custom field in Woocommerce Edit Account page
Hope this helps.

Reorder custom "repeat password field" for woocommerce my account registration

Can someone take time to help me with what is stated down below?
Goal:
Reorder my "custom-repeat-password-field".
Implemented code
function wc_register_form_password_repeat() {
?>
<p class="form-row form-row-wide">
<label for="reg_password2"><?php _e( 'Password Repeat', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="password" class="input-text" name="password2" id="reg_password2" value="<?php if ( ! empty( $_POST['password2'] ) ) echo esc_attr( $_POST['password2'] ); ?>" />
</p>
<?php
}```

Payment Method Selected on Woocommerce Cart page should be active on Checkout Page

I had added three buttons to the cart page, one for each payment method. Clicking on one of the buttons led to the checkout page where the corresponding payment method used to be pre-selected. It used to work, but somehow has stopped working after updating to the latest Woocommerce version. Any other way of doing this?
Here is the code in cart.php template for the buttons:
<form action="<?php echo esc_url( WC()->cart->get_cart_url() ); ?>" method="post">
<input type="submit" class="checkout-button button alt wc-forward" name="proceed" value="<?php _e( 'Order with Purchase Order', 'woocommerce' ); ?>" />
<input type="submit" class="checkout-button button alt wc-forward" name="proceed" value="<?php _e( 'Order with PayPal', 'woocommerce' ); ?>" />
<input type="submit" class="checkout-button button alt wc-forward" name="proceed" value="<?php _e( 'Order with Credit Card', 'woocommerce' ); ?>" />
<?php /*do_action( 'woocommerce_proceed_to_checkout' );*/ ?>
<?php wp_nonce_field( 'woocommerce-cart' ); ?>
</form>

WordPress search only works on other pages only work in home page

I'm working on my own Avada Theme, only my WordPress homepage search working. other pages search not working I have attached all codes Any idea how to solve the issue? I have attached my search code.
Searchform.php
<?php
/**
* The search-form template.
*
* #package Avada
* #subpackage Templates
*/
// Do not allow directly accessing this file.
if ( ! defined( 'ABSPATH' ) ) {
exit( 'Direct script access denied.' );
}
?>
<form role="search" class="searchform" method="get" action="<?php echo home_url();?>"
<div class="search-table">
<div class="search-field">
<input type="text" value="" name="s" class="s" placeholder="<?php esc_html_e( 'Search ...', 'Avada' ); ?>" required aria-required="true" aria-label="<?php esc_html_e( 'Search ...', 'Avada' ); ?>"/>
</div>
<div class="search-button">
<input type="submit" class="searchsubmit" value="" alt="<?php esc_attr_e( 'Search', 'Avada' ); ?>" />
</div>
</div>
</form>

Resources