I have a user registration form from woocommerce where users can register to create a account. Right now the username generated is first name. Is it possible to use the billing_company field as the username upon a woocommerce registration instead of the first name?
You should use a custom function hooked into woocommerce_new_customer_data filter hook. This code will combine first name and last name as a username. Better than using the billing company
add_filter( 'woocommerce_new_customer_data', 'custom_new_customer_data', 10, 1 );
function custom_new_customer_data( $cust_customer_data ){
// get the first and last billing names
if(isset($_POST['billing_first_name'])) $first_name = $_POST['billing_first_name'];
if(isset($_POST['billing_last_name'])) $last_name = $_POST['billing_last_name'];
// the customer billing complete name
if( ! empty($first_name) || ! empty($last_name) ) {
$user_name = $first_name . ' ' . $last_name;
}
// Replacing 'user_login' in the user data array, before data is inserted
if( ! empty($user_name ) ) {
$cust_customer_data['user_login'] = sanitize_user( str_replace( ' ', '_', $user_name ) );
}
return $cust_customer_data;
}
Related
I'm trying to add custom meta to my new order emails. At this moment, custom meta shows up when I use the "Resend new order notification", but it doesn't when a purchase is made through the website.
I suspect this has to do with my code not being able to check the Order Details before sending the email notification. Here's the code I came up with so far..
// Ref: https://www.businessbloomer.com/woocommerce-add-extra-content-order-email/
function custom_order_type_number_email( $order, $sent_to_admin, $plain_text, $email ) {
// Get custom Order Type and Order Number meta keys
$custom_order_type = get_post_meta( $order->get_id(), 'custom_order_type', true );
$custom_order_number = get_post_meta( $order->get_id(), 'custom_order_number', true );
// Add for New Order email notification only
if ( $email->id == 'new_order' ) {
if ( !empty( $custom_order_type ) ) {
echo '<p><b>Order type :</b> ' . $custom_order_type . '</p>';
} else {
echo '<p><b>Order type :</b> Website</p>';
}
if ( !empty( $custom_order_number ) ) {
echo '<p><b>Order no :</b> ' . $custom_order_number . '</p>';
} else {
echo '<p><b>Order no :</b> New</p>';
}
}
}
add_action( 'woocommerce_email_after_order_table', 'custom_order_type_number_email', 20, 4 );
What I'm trying to do ideally is..
When the customer purchases from the website, this new order will be without the custom meta. So the custom meta in the email will show Order type: Website / Order number: New.
And if the admin manually adds a new order with defined custom meta, this new order email notification would get and show the saved custom meta later.
I hope this made sense. (>_<) And thanks in advance for the help.
I'm coming across an issue when trying to register a second user account once someone registers as a customer via WooCommerce. I have added the following woocommerce_created_customer hook:
add_action('woocommerce_created_customer', function($customer_id)
{
if(isset($_POST['second_user_first_name']) && isset($_POST['second_user_last_name']))
{
$createSecondUserId = wp_create_user(strtolower($_POST['second_user_first_name'].'-'.$_POST['second_user_last_name']).'-'.$customer_id, wp_generate_password(), 'test#test.com');
if(is_wp_error($createSecondUserId))
{
$errors = $createSecondUserId->errors;
print_r($errors);
die();
}
}
});
However I get the following error when submitting a new WooCommerce registration:
Array ( [existing_user_login] => Array ( [0] => Sorry, that username already exists! ) )
It's strange as I'm setting a random username within the wp_create_user function, so the usernames should not clash. Has anyone got any ideas?
You can use username_exists() to determines that the given username exists.
add_action( 'woocommerce_created_customer', function($customer_id){
if( isset( $_POST['second_user_first_name'] ) && isset( $_POST['second_user_last_name'] ) ) {
if( !username_exists( strtolower( $_POST['second_user_first_name'].'-'.$_POST['second_user_last_name'] ).'-'.$customer_id ) ){
$createSecondUserId = wp_create_user( strtolower( $_POST['second_user_first_name'].'-'.$_POST['second_user_last_name'] ).'-'.$customer_id, wp_generate_password(), 'test#test.com' );
if(is_wp_error($createSecondUserId)){
$errors = $createSecondUserId->errors;
print_r($errors);
die();
}
}
}
});
If the username already exists you can create a new one by adding a progressive numeric suffix. In this way you will be sure that the username of the second account will always be unique.
Note that if you run multiple tests with your current code you need to
make sure you remove the user with the email address test#test.com
otherwise you will get an error: [existing_user_email] => Sorry, that email address is already used!.
add_action('woocommerce_created_customer', function( $customer_id ) {
if ( isset($_POST['second_user_first_name']) && isset($_POST['second_user_last_name']) ) {
// create the username based on the form data
$username = strtolower( $_POST['second_user_first_name'] . '-' . $_POST['second_user_last_name'] ) . '-' . $customer_id;
// if the username already exists it creates a unique one
if ( username_exists($username) ) {
$i = 0;
while ( username_exists($username) ) {
$username = $username . '-' . ++$i;
}
}
// create the second user
$createSecondUserId = wp_create_user( $username, wp_generate_password(), 'test#test.com' );
}
});
The code has been tested and works. Add it to your active theme's functions.php.
This question already has answers here:
Customizing email headers in WooCommerce email notifications
(1 answer)
How to add Custom Field as a CC to WooCommerce Customer Order Email
(1 answer)
Woocommerce: Adding second email address not working, unless recipient is admin
(2 answers)
Closed 3 years ago.
I have a custom field that contains an additional customer email account.
My idea is that when an order changes state WAIT, PENDING, PROCESSING or COMPLETED, it will reach the email of the one configured in this field.
Is this possible?
There is no problem that requires programming, but I don't know what hook to use.
Thank you.
Add the follows code snippet in your active theme's functions.php -
function add_cc_to_wc_order_emails( $header, $mail_id, $mail_obj ) {
$available_for = array( 'customer_on_hold_order', 'customer_processing_order', 'customer_completed_order' );
if( in_array( $mail_id, $available_for ) ) {
$cc_email = 'addyour#ccmail.com';
$cc_username = "yourCCUser";
$formatted_email = utf8_decode( $cc_username . ' <' . $cc_email . '>' );
$header .= 'Cc: ' . $formatted_email . "\r\n";
}
return $header;
}
add_filter( 'woocommerce_email_headers', 'add_cc_to_wc_order_emails', 99, 3 );
This might be quite useful:
https://www.skyverge.com/blog/add-woocommerce-email-recipients-conditionally/
I would take a look at the Considerations section.
You could use woocommerce_order_status_changed hook for example to notify someone each time an order change of status, like in this example:
add_action('woocommerce_order_status_changed', 'send_custom_email_notifications', 10, 4 );
function send_custom_email_notifications( $order_id, $old_status, $new_status, $order ){
$to_email = 'john.doe#gmail.com'; // <= Replace with your email custom field (the recipient)
$shop_name = __('Shop name'); // Set the shop name
$admin_email = 'shop#email.com'; // Set default admin email
$subject = sprintf( __('Order %s has changed to "%s" status'), $order_id, $new_status ); // The subject
$message = sprintf( __('Order %s has changed to "%s" status'), $order_id, $new_status ); // Message content
$headers = sprintf( __('From: %s <%s>'), $shop_name, $admin_email ) . "\r\n"; // From admin email
wp_mail( $to_email, $subject, $message, $headers ); // Send the email
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works
I am using Woo Commerce with WC Vendor and WC Booking plugin. I want to send booking notification to vendor. Currently it sends notification to Customer and Administrator and when admin changes product status to processing & completed, then it sends notification to vendor. However, I want to send vendor notification along with admin notification.
I tried this hook:
add_action( 'woocommerce_new_booking', 'new_order_email_to_vendor', 10, 4 );
function new_order_email_to_vendor( $order ){
$emails = WC()->mailer()->get_emails();
if ( ! empty( $emails ) ) {
$emails['WC_Product_Vendors_Order_Email_To_Vendor']->trigger( $order );
}
}
But it throws an error:
Fatal error: Call to a member function get_date_created() on boolean in /wp-content/plugins/woocommerce-product-vendors/includes/emails/class-wc-product-vendors-order-email-to-vendor.php on line 56
So, now I am trying to hook vendor email directly along with customer and administrator email in this line:
$this->recipient = $this->get_option( 'recipient', get_option( 'admin_email' ), 'WILL ADD VENDOR EMAIL HERE' );
in file:
wp-content/plugins/woocommerce-bookings/includes/emails/class-wc-email-new-booking.php
At this stage, I have bookable product id available and I am trying to pull vendor information using product id but I don't found any information.
I tried:
get_post()
get_post_meta()
get_post_meta_by_id()
The Question is: How to get vendor information (specifically email) using product id?
I don't have and I have never used WC Vendors plugin as this is a non official commercial plugin (not made by automatic).
To get the vendor ID (after searching a bit) you can get it this way from a product ID:
$vendor_id = get_post_field( 'post_author', $product_id );
Now you can get the vendor email this way:
$vendor_id = get_post_field( 'post_author', $product_id );
$vendor = get_userdata( $vendor_id );
$email = $vendor->user_email;
May be a good turn around:
You can use the dedicated filter hook woocommerce_email_recipient_{$this->id} where $this->id is the ID of the notification type, for new_booking email ID (and also for testing new_order email ID too).
This will allow you to add additional email recipients.
In email notifications hooks, the Order object is nearly always defined. As In an order you can have many items (different products rom different vendors), you will need to get the vendor ID from each.
In the code below I add to the recipients the vendors emails for new_booking and new_order email notifications:
add_filter( 'woocommerce_email_recipient_new_booking', 'additional_customer_email_recipient', 10, 2 );
add_filter( 'woocommerce_email_recipient_new_order', 'additional_customer_email_recipient', 10, 2 ); // Optional (testing)
function additional_customer_email_recipient( $recipient, $order ) {
if ( ! is_a( $order, 'WC_Order' ) ) return $recipient;
$additional_recipients = array(); // Initializing…
// Iterating though each order item
foreach( $order->get_items() as $item_id => $line_item ){
// Get the vendor ID
$vendor_id = get_post_field( 'post_author', $line_item->get_product_id());
$vendor = get_userdata( $vendor_id );
$email = $vendor->user_email;
// Avoiding duplicates (if many items with many emails)
// or an existing email in the recipient
if( ! in_array( $email, $additional_recipients ) && strpos( $recipient, $email ) === false )
$additional_recipients[] = $email;
}
// Convert the array in a coma separated string
$additional_recipients = implode( ',', $additional_recipients);
// If an additional recipient exist, we add it
if( count($additional_recipients) > 0 )
$recipient .= ','.$additional_recipients;
return $recipient;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This should work without errors.
When people are buying a product through the WooCommerce extension, I have enabled that they can create an account on checkout. I don't let them choose their own username and password.
Now I see that WP uses some part of the emailaddress to create a username, and the display name is based on the first name filled in on checkout.
Now I want to change that:
username must be the complete emailaddress [SOLVED];
display name must be the first name + last name [UNSOLVED].
I tried this: for display name with my 'no knowledge' of PHP:
add_filter('pre_user_display_name', 'wsis_pre_user_display_name');
function wsis_pre_user_display_name($display_name) {
$first = get_user_field("billing_first_name");
$last = get_user_field("billing_last_name");
$display_name = $first . $last;
return $display_name;
}
This filter is mentioned in their codex: http://codex.wordpress.org/Function_Reference/wp_update_user. But no examples and my code didn't work. Anybody can help?
In user.php wp-includes folder I found the filter, now get it working :-).
/**
* Filter a user's display name before the user is created or updated.
*
* #since 2.0.3
*
* #param string $display_name The user's display name.
*/
$display_name = apply_filters( 'pre_user_display_name', $display_name );
if ( empty($description) )
$description = '';
Second try did something! It left the display name completely empty:
add_filter('pre_user_display_name', 'pre_user_display_name');
function pre_user_display_name($display_name) {
$first = get_the_author_meta('first_name');
$last = get_the_author_meta('last_name');
$display_name = $first . $last;
return $display_name;
}
Am I on the right track?
To set the username as complete email address, you can add following code in functions.php file of your theme.
add_filter('woocommerce_new_customer_data','change_username');
function change_username($user_data)
{
return array(
'user_login' => $user_data['user_email'],
'user_pass' => $user_data['user_pass'],
'user_email' => $user_data['user_email'],
'role' => 'customer'
);
}
Here is how to set the display name to first name + last name.
// Sets the display name to first name and last name
add_filter( 'pre_user_display_name' , 'default_display_name' );
function default_display_name($name) {
if ( isset( $_POST['billing_first_name'] ) ) {
$firstname = sanitize_text_field( $_POST['billing_first_name'] );
}
if ( isset( $_POST['billing_last_name'] ) ) {
$lastname = sanitize_text_field( $_POST['billing_last_name'] );
}
$name = $firstname . ' ' . $lastname;
return $name;
}
Source : http://geektamin.com/blog/533/why-update_user_meta-display_name-doesnt-work-and-how-to-use-pre_user_display_name-instead/