Woocommerce wc_create_new_customer override on checkout - woocommerce

I am using the guest checkout and have enabled "Automatically generate username from customer email" and "Automatically generate customer password", also I created a hidden input
<input class="input-checkbox" id="createaccount" <?php checked( ( true === $checkout->get_value( 'createaccount' ) || ( true === apply_filters( 'woocommerce_create_account_default_checked', false ) ) ), true) ?> type="checkbox" name="createaccount" value="1" /> <label for="createaccount" class="checkbox"><?php _e( 'Create an account?', 'woocommerce' ); ?></label> , which helps automatically create a user on checkout so customers didn't know that a user has been generated by their email. But if the same user, with the same email tries to fill the same email on the checkout field, receives the message: "An account is already registered with your email address. Please login." , which comes from wc_create_new_customer function inside the /woocommerce/includes/class-wc-checkout.php.
I would like to override wc_create_new_customer function and return the $customer_id for the existing user instead of firing and error for already registered account. Tried hooks and filters, but none of them works. Any help?
Thanks in advance!

Related

WordPress, User front end editing, can't update email and personal information

I want to create a form, where registered user can edit its own information,
everything is working except email, it's not updating.
I found some questions about that but no answers.
I shorted a code, left only user first name and user email, to show that user name is working, but not email. Here it is:
add_action('init', '_themename_edit_user_data');
function _themename_edit_user_data(){
$current_user = wp_get_current_user();
$user_id = $current_user->ID;
if ( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action'] ) && $_POST['action'] == 'update-user' ) {
/* Update user information. */
if ( !empty( $_POST['email'] ) ){
wp_update_user( array ('ID' => $user_id, 'user_email' => sanitize_email( $_POST['email'] )));
}
if ( !empty( $_POST['first-name'] ) ) {
update_user_meta( $user_id, 'first_name', esc_attr( $_POST['first-name'] ) );
}
}
}
Here is my form:
<form method="post" id="adduser" action="<?php the_permalink(); ?>">
<p class="form-username">
<label for="first-name"><?php _e('First Name', 'profile'); ?></label>
<input class="text-input" name="first-name" type="text" id="first-name" value="<?php the_author_meta( 'first_name', $current_user->ID ); ?>" />
</p><!-- .form-username -->
<p class="form-email">
<label for="email"><?php _e('E-mail *', 'profile'); ?></label>
<input class="text-input" name="email" type="text" id="email" value="<?php the_author_meta( 'user_email', $current_user->ID ); ?>" />
</p><!-- .form-email -->
<p class="form-submit">
<input name="updateuser" type="submit" id="updateuser" class="submit button" value="<?php _e('Update', 'profile'); ?>" />
<?php wp_nonce_field( 'update-user' ) ?>
<input name="action" type="hidden" id="action" value="update-user" />
</p><!-- .form-submit -->
</form><!-- #adduser -->
What am I doing wrong?
I have to react to this post. It would be criminal not to point out all the security problems you're currently facing. Warning it's long to read but short to understand.
I'm far from being an expert but most of the people looking at posts on Stackoverflow regarding front-end user data inputs and updates are (usually) mostly new to Wordpress and are here to learn. It's easy to get overwhelmed. Let's go easy and get started.
First of all, when checking permissions, you should always use triple operators. === instead of ==. It doesn't seems like much but one means EQUAL and the other one means IDENTICAL. You can learn more about Comparison Operators here.
Checking the identity of a user is your only line of defense in regards to malicious practices. Granting front end editing capability is just a series of conditional statement a user MUST pass before being granted access to the database. Let's not mess around.
My assumption is that you're letting your users update their personal informations from their user profile page served by the author.php template. Therefore the following thinking is based around it, but can be easily adapted. I have to insist that nothing is constrain to any templates. Here is the simple form we're going to use, currently in our author.php template. It's a simplified version of your form.
<form method="POST">
<input type="text" name="first_name" value="<?php echo esc_attr( wp_get_current_user()->first_name ); ?>">
<input type="email" name="user_email" value="<?php echo esc_attr( wp_get_current_user()->user_email ); ?>">
<?php wp_nonce_field( esc_attr( 'update-user-' . get_current_user_id() ), esc_attr( 'nonce-user-' . get_current_user_id() ) ); ?>
<button type="submit">Submit</button>
</form>
For clarity and consistency, it's always a good idea to use Wordpress default function when you can. get_current_user_id() Get the current user’s ID, instead of wp_get_current_user()->ID.
Let's talk about action's hook. init is a hook that fire really early in the Wordpress firing sequence.
Fires after WordPress has finished loading but before any headers are sent.
The WP_Object hasn't even finished to set up. When looking for the right hook you can refer to the Plugin API/Action Reference. A more suiting firing hook would be wp which is the recommended hook for any high-level filtering or validation, following queries, but before WordPress does any routing, processing, or handling.
Fires once the WordPress environment has been set up. After WP object is set up.
add_action( 'wp', 'wpso62938497_user_frontend_privy_editing' );
function wpso62938497_user_frontend_privy_editing() {
//...
};
The "hors d'oeuvre" of user checking in regards to front end editing is to know if the user is actually logged in. Which you are missing to do. We can use is_user_logged_in() which determines whether the current visitor is a logged in user.
We also want to be sure that the user actually on the author.php page is the page owner. get_current_user_id() === get_queried_object()->ID will do just that. We will also be checking if the page we're on is an author page and has a WP_User object set up. Finally we will compare both queried user and page author to be sure both are the same.
add_action( 'wp', 'wpso62938497_user_frontend_privy_editing' );
function wpso62938497_user_frontend_privy_editing() {
/**
* Determines whether the current visitor is a logged in user.
* Retrieves the currently queried object. Check whether an it belongs to a WP_User class.
* Determines whether the query is for an existing author archive page. Compare it to the current logged in user ID.
* Compare current logged in user ID with the current queried ID.
*/
if ( is_user_logged_in() && get_queried_object() instanceof \WP_User && is_author( get_current_user_id() ) && get_current_user_id() === get_queried_object()->ID ) {
//...
};
};
Let's talk about nonce. In your form you're declaring a nonce but you're not checking against it. A nonce is a "number used once" to help protect URLs and forms from certain types of misuse, malicious or otherwise. It's like you serial number from your ID card, that number is you. A nonce is your temporary ID card for 24 hours. As you can imagine, it's quite important. Wordpress as a whole page on Nonces, you should have a read. We will also be checking the REQUEST_METHOD.
add_action( 'wp', 'wpso62938497_user_frontend_privy_editing' );
function wpso62938497_user_frontend_privy_editing() {
/**
* Determines whether the current visitor is a logged in user.
* Retrieves the currently queried object. Check whether an it belongs to a WP_User class.
* Determines whether the query is for an existing author archive page. Compare it to the current logged in user ID.
* Compare current logged in user ID with the current queried ID.
*/
if ( is_user_logged_in() && get_queried_object() instanceof \WP_User && is_author( get_current_user_id() ) && get_current_user_id() === get_queried_object()->ID ) {
/**
* Determines whether the POST request method was used to access the page.
* Determine if our nonce variable is declared and is different than null.
* Verifies that a correct security nonce was used with time limit.
*/
if ( 'POST' === $_SERVER['REQUEST_METHOD'] && isset( $_POST['nonce-user-' . get_current_user_id()] ) && wp_verify_nonce( $_POST['nonce-user-' . get_current_user_id()], 'update-user-' . get_current_user_id() ) ) {
//...
};
};
};
We're nearly done! For any sanitization requirements you can check the following post which states what data is sanitize or not by wp_insert_user() or wp_update_user().
Of course you should restrict the form using javascript, but javascript can easily be disabled. That's why we also need a check on the php side.
There is also a case to have in mind and handle, which is the constant prompt to submit on page refresh, F5, CTRL+R after a submission. That behavior can be avoided by redirecting the user to the previous page, and setting a 303 header. You can read more about that issue here.
Finally we're done, and our script is safe to use on the front end. And we're feeling like this!
add_action( 'wp', 'wpso62938497_user_frontend_privy_editing' );
function wpso62938497_user_frontend_privy_editing() {
/**
* Determines whether the current visitor is a logged in user.
* Retrieves the currently queried object. Check whether an it belongs to a WP_User class.
* Determines whether the query is for an existing author archive page. Compare it to the current logged in user ID.
* Compare current logged in user ID with the current queried ID.
*/
if ( is_user_logged_in() && get_queried_object() instanceof \WP_User && is_author( get_current_user_id() ) && get_current_user_id() === get_queried_object()->ID ) {
/**
* Determines whether the POST request method was used to access the page.
* Determine if our nonce variable is declared and is different than null.
* Verifies that a correct security nonce was used with time limit.
*/
if ( 'POST' === $_SERVER['REQUEST_METHOD'] && isset( $_POST['nonce-user-' . get_current_user_id()] ) && wp_verify_nonce( $_POST['nonce-user-' . get_current_user_id()], 'update-user-' . get_current_user_id() ) ) {
if ( isset( $_POST['first_name'] ) && ! empty( $_POST['first_name'] ) && wp_get_current_user()->first_name !== $_POST['first_name'] && strcasecmp( sanitize_text_field( $_POST['first_name'] ), $_POST['first_name'] ) ) {
update_user_meta( get_current_user_id(), 'first_name', sanitize_text_field( $_POST['first_name'] ), esc_attr( wp_get_current_user()->first_name ) );
};
if ( is_email( sanitize_email( $_POST['user_email'] ) ) && strcasecmp( sanitize_email( $_POST['user_email'] ), $_POST['user_email'] ) ) {
$userdata = array (
'ID' => get_current_user_id(),
'user_email' => $_POST['user_email'],
);
wp_update_user( $userdata );
};
wp_safe_redirect( esc_url( get_author_posts_url( get_current_user_id() ) ), 303 );
exit;
};
};
};
This function is missing any error handling, which is pretty much adding else statements.
Some final wised words: "Sanitize Inputs, Escape Outputs". https://developer.wordpress.org/themes/theme-security/data-sanitization-escaping/
Give the try to my answer:
$args = array(
'ID' => $user_id,
'user_email' => esc_attr( $_POST['email'] )
);
wp_update_user( $args );
Sorry, guys! I found out that I have not right condition check, that was a problem!
For sure, everybody use the same code:
if ( !empty( $_POST['email'] ) ){
if (!is_email(sanitize_email( $_POST['email'] ))) {
$error[] = __('The Email you entered is not valid. please try again.', 'profile');
} elseif( email_exists(sanitize_email( $_POST['email'] )) != $user_id ) {
$error[] = __('This email is already used by another user. try a different one.', 'profile');
} else {
wp_update_user( array ('ID' => $user_id, 'user_email' => sanitize_email( $_POST['email'] )));
}
}
The problem is here:
elseif( email_exists(sanitize_email( $_POST['email'] )) != $user_id )
It must be:
elseif( email_exists(sanitize_email( $_POST['email'] )) == $user_id )
Sorry!

Add exrtra user approve status filed in user profile, visible to admin only and send mail if checkbox is checked at first time in wordpress?

I want to give the functionality to admin to approve user status manually. I was able to give this functionality, but having some issue in this functionality. How can I hide this field from user's profile for user role. i.e. Field should be visible to admin only. If I hide this filed from user profile using jQuery then when user hits update profile button at that time value is updated. I want value to be same as per user selected (set by admin). I also want to send mail to user if checkbox is selected from uncheck to check, but currently it is sending mail every time. How can i solve out this issue?
/** Add user approve field */
add_action( 'user_new_form', 'Add_user_fields' );
add_action( 'edit_user_profile', 'Add_user_fields' );
add_action( 'show_user_profile', 'Add_user_fields' );
function Add_user_fields( $user ) { ?>
<h2 class="user_prmission">User Permission</h3>
<table class="form-table">
<tr class="user-approve_status-wrap">
<th><label for="dropdown">Approve User Permission</label></th>
<td>
<?php
//get dropdown saved value
$checked = (isset($user->artwork_approved) && $user->artwork_approved) ? ' checked="checked"' : '';
?>
<label for="artwork_approved">
<input name="artwork_approved" type="checkbox" id="artwork_approved" value="1" <?php echo $checked; ?>>
<?php _e('Approve Status','AA'); ?>
</label>
</td>
</tr>
</table>
<?php
}
/* Update selected option **/
add_action( 'user_register', 'save_user_fields');
add_action( 'personal_options_update', 'save_user_fields' );
add_action( 'edit_user_profile_update', 'save_user_fields' );
function save_user_fields( $user_id ) {
if ( !current_user_can( 'edit_user', $user_id ) )
return false;
update_user_meta($user_id, 'artwork_approved', isset($_POST['artwork_approved']));
/* Send email to agent to notify about thier account is approved. **/
if (get_user_meta($user_id, 'artwork_approved', true)) {
// sent mail if checkbox is selected from unchecked to checked,and hide this filed from user profile only visible to admin.
}
}
What I understand from your question is, you have added a custom field on user profile which is a checkbox. You want that field to be editable only by admins and not by the users.
If this understanding is correct, you can check the user capabilities of current user while rendering the custom field on user profile page.
That way, if current user has administrator privileges only then the custom field will be rendered. If a non admin user is logged in then the custom field will not be rendered.
Also, in your function to add custom field, you are setting the value of checkbox to '1' irrespective of whether it is checked or not. I guess that is causing the email to be sent every time. You should set the value of checkbox based on your condition.
So your function to add custom field will become as follows.
/** Add user approve field */
add_action( 'user_new_form', 'Add_user_fields' );
add_action( 'edit_user_profile', 'Add_user_fields' );
add_action( 'show_user_profile', 'Add_user_fields' );
function Add_user_fields( $user ) { ?>
if( !current_user_can( 'manage_options' ) ){
return;
}
<h2 class="user_prmission">User Permission</h3>
<table class="form-table">
<tr class="user-approve_status-wrap">
<th><label for="dropdown">Approve User Permission</label></th>
<td>
<?php
//get dropdown saved value
if( isset($user->artwork_approved) && $user->artwork_approved ){
$checked = 'checked="checked"';
$value = '1';
}else{
$checked = null;
$value = null;
}
?>
<label for="artwork_approved">
<input name="artwork_approved" type="checkbox" id="artwork_approved" value="<?php echo $value; ?>" <?php echo $checked; ?>>
<?php _e('Approve Status','AA'); ?>
</label>
</td>
</tr>
</table>
<?php
}
Hope this helps.

Wordpress Custom field doesn't update DB consistently

I'm creating a custom field on user-edit admin page. I added the custom code to functions.php.
Problem: Sometimes it updates the db and sometimes it doesn't update the db.
I thought it was caching but it's not that. Can someone tell me why it would be updating sometimes but not all the time? Do you see a problem with my code?
Code:
add_action( 'show_user_profile', 'be_show_extra_profile_fields' );
add_action( 'edit_user_profile', 'be_show_extra_profile_fields' );
function be_show_extra_profile_fields( $user ) { ?>
<table class="form-table">
<tr>
<th><label for="contact">Phone</label></th>
<td>
<input type="text" name="phone" id="phone" value="<?php echo esc_attr( get_the_author_meta( 'phone', $user->ID ) ); ?>" class="regular-text" /><br />
<span class="description">Enter phone number.</span>
</td>
</tr>
</table>
<?php }
add_action( 'personal_options_update', 'be_save_extra_profile_fields' );
add_action( 'edit_user_profile_update', 'be_save_extra_profile_fields' );
function be_save_extra_profile_fields( $user_id ) {
if ( ! current_user_can( 'edit_user', $user_id ) ) {
return false;
}
update_usermeta( $user_id, 'phone', esc_attr( $_POST['phone'] ) );
}
UPDATE
I now know why the admin form updates the db sometimes and sometimes it does not update the db. The admin form has a phone field plus on the profile page there's phone field also. When I updated the phone in admin and refreshed the page on the profile page it updated it when the textbox was not filled in. When the textbox was filled in and I updated the form in admin, refreshing the profile page would insert the phone number from the profile page. So there's an issue with the profile page, it inserts data on refresh.
I now know why the admin form updates the db sometimes and sometimes it does not update the db. The admin form has a phone field plus on the profile page there's phone field also. When I updated the phone in admin and refreshed the page on the profile page it updated it when the textbox was not filled in. When the textbox was filled in and I updated the form in admin, refreshing the profile page would insert the phone number from the profile page. So there's an issue with the profile page, it inserts data on refresh. The admin form was updating the db. The profile form was making it seem it was not updating because when refreshed it would update the db with that value.

check registration custom fields are filed by logged in user woocommerce

In woocommerce customer registration I need to add 2 additional fields (mandatory) year of passing (select box), Name of college (select box).
I need to add these 2 fields to the registration process and prompt existing users to fill them if they try to login.
As in the process will be as follows
User tries to login (need to check whether the above fields are filled by user or not - If yes then make him logged in else proceed to step 2)
Will get registration page / form to fill in the above additional fields.
He will then get logged in to the site.
Thanks in advance
Yes, that can be done.
As per I understood, you want to add some extra fields to your registration page. Here's how:
add_action( 'register_form', 'myplugin_register_form' );
function myplugin_register_form() {
$first_name = ( ! empty( $_POST['first_name'] ) ) ? trim( $_POST['first_name'] ) : '';
?>
<p>
<label for="first_name"><?php _e( 'Full Name', 'mydomain' ) ?><br />
<input type="text" name="first_name" id="first_name" class="input" value="<?php echo esc_attr( wp_unslash( $first_name ) ); ?>" size="25" required /></label>
</p>
<?php
}
Put the code in function.php and there you go.
It will work perfectly.

BuddyPress Xprofile fields to display on "wordpress user edit admin panel"

I am building a buddypress/bbpress, website with xprofile registration fields. I am using New User Approve plugin to approve each users manually since we need to check information of each user before they get activated.
Problem here is, I am unable to check/view the xprofile field values in Wordpress user edit admin panel. All I have is the username change password, changing roles etc. I want the admin panel to display the extra information of the registered user so that I can check the info and approve . Anyone can help me out to solve this problem.
Might be similar to this.. haven't tried the code though....
Replace the key value 'xprofile_key_birthday' with actual xprofile keys in Buddypress DB.
Note: This code only displays the values on the edit screen and doesn't insert or update anything.
<?php
add_action( 'show_user_profile', 'showmy_extra_profile_fields' );
add_action( 'edit_user_profile', 'showmy_extra_profile_fields' );
function showmy_extra_profile_fields( $user ) { ?>
<h3>Extra profile information</h3>
<table class="form-table">
<tr>
<th><label>xprofile_key_birthday</label></th>
<td>
<?php
if( function_exists( 'xprofile_get_field_data' ) ) {
$xprofile_value = xprofile_get_field_data('xprofile_key_birthday', $user->ID );
}
else {
$xprofile_value = '';
}
?>
<input type="text" name="xprofile_key_birthday" id="xprofile_key_birthday" value="<?php echo esc_attr( $xprofile_value ); ?>" class="regular-text" readonly />
</td>
</tr>
</table>
<?php
}
?>
I use the free Wangguard plugin on my BuddyPress/bbPress website. All I need to do is click on "Users" in the Wangguard menu on Wordpress dashboard sidebar and then click on "BP Profile" under the member username column. I can view and even edit the member profile from there. Hope it helps.

Resources