We added new fields with new variables for the registration form, and we want to receive in our email all the data in the fields listed for the new client account at the moment of the account creation.
add_action('woocommerce_created_customer',
'woocommerce_created_customer_admin_notification');
function woocommerce_created_customer_admin_notification($customer_id)
{
wp_send_new_user_notifications($customer_id, 'admin');
}
The part of the code that I have attached to this email is only sending us the email and username of the account that has been created. However, we want to receive all the data as mentioned before.
/**
* Filters the contents of the new user notification email sent to the site admin.
*
* #since 4.9.0
*
* #param array $wp_new_user_notification_email_admin {
* Used to build wp_mail().
*
* #type string $to The intended recipient - site admin email address.
* #type string $subject The subject of the email.
* #type string $message The body of the email.
* #type string $headers The headers of the email.
* }
* #param WP_User $user User object for new user.
* #param string $blogname The site title.
*/
$wp_new_user_notification_email_admin = apply_filters( 'wp_new_user_notification_email_admin', $wp_new_user_notification_email_admin, $user, $blogname );
Use this wp_new_user_notification_email_admin filter and add the details to the message parameter.
$wp_new_user_notification_email_admin['message'].= "Test data";
See below for an implementation sample.
add_action('login_init', 'set_wp_new_user_notification_email_admin_init');
function set_wp_new_user_notification_email_admin_init() {
add_filter('wp_new_user_notification_email_admin', 'set_wp_new_user_notification_email_admin', 10, 3);
}
function set_wp_new_user_notification_email_admin($wp_new_user_notification_email, $user, $blogname) {
$wp_new_user_notification_email['subject'] = sprintf('[%s] New user %s registered.', $blogname, $user->user_login);
$wp_new_user_notification_email['message'] = sprintf("%s ( %s ) has registerd to your blog %s.", $user->user_login, $user->user_email, $blogname);
return $wp_new_user_notification_email;
}
Related
I have setup Woocommerce to automatically register a new customer when the order is completed.
Now I want to send the password and other things that has been generated to a third party using a API POST request to create the same user account.
Things I need to send from the Woocommerce generated account:
Email address (used for email and login on third party website)
First name
Last name
Password (Needs to be unhashed, same as used in new account email)
Can someone show me an example how to get this done? Or point me in to the right direction? I just can't find anything to start with.
I thought by adding Curl to the Woocommerce thank you page webhook. But this won't send the password unhashed, it just stay blank.
Hope someone knows an easy way to get this done.
Thanks!
Latest UPDATE: CODE USING IN MY FUNCTIONS.PHP
class NewCustomerRegistration
{
private $credentials;
public function __construct()
{
// Use PHP_INT_MAX so that it is the last filter run on this data
// in case there are other filter changing the password, for example
add_filter(
'woocommerce_new_customer_data',
[$this, 'when_user_is_created'],
1,
PHP_INT_MAX
);
add_action('woocommerce_new_customer', [$this, 'when_customer_is_created']);
}
public function when_user_is_created($customerData)
{
$this->credentials = [
'email' => $customerData['user_email'],
'password' => $customerData['user_pass'],
];
return $customerData;
}
public function when_customer_is_created($customerId)
{
$customer = get_userdata($customerId);
/**
* Perform the required actions with collected data
*
* Email: $this->credentials['email']
* Password: $this->credentials['password']
* First Name: $customer->first_name
* Last Name: $customer->last_name
*/
// Testing sending email function
$subject = "Test Email with data";
$email = "info#mydomain.com";
$message = "Hello, {$customer->first_name}\n\n";
$message .= "Here are your login details for {$customer->first_name} {$customer->last_name}\n\n";
$message .= "Your company is: {$customer->company}\n\n";
$message .= "Your username is: {$this->credentials['email']}\n\n";
$message .= "Your password is: {$this->credentials['password']}\n\n";
$message .= "Your email is: {$this->credentials['email']}\n\n";
$message .= "Your role is: {$customer->role}\n\n";
$headers = array();
add_filter( 'wp_mail_content_type', function( $content_type ) {return 'text/html';});
$headers[] = 'From: My Wordpress Website <info#mydomain.com>'."\r\n";
wp_mail( $email, $subject, $message, $headers);
// Reset content-type to avoid conflicts
remove_filter( 'wp_mail_content_type', 'set_html_content_type' );
}
}
It looks like the combining the actions woocommerce_created_customer (for email and password) and woocommerce_new_customer (for other customer details) could do the job for you.
My thinking is that you could do something like..
class NewCustomerRegistration
{
private $credentials;
public function __construct()
{
add_action('woocommerce_created_customer', [$this, 'when_user_is_created']);
add_action('woocommerce_new_customer', [$this, 'when_customer_is_created']);
}
public function when_user_is_created($customerId, $customerData)
{
$this->credentials = [
'email' => $customerData['user_email'],
'password' => $customerData['user_pass'],
];
}
public function when_customer_is_created($customerId)
{
$customer = get_userdata($customerId);
/**
* Send email with collected data
*
* Email: $this->credentials['email']
* Password: $this->credentials['password']
* First Name: $customer->first_name
* Last Name: $customer->last_name
*/
wp_mail(...);
}
}
NOTE You should probably clear the credentials after sending so that, if the woocommerce_new_customer action is called with a different user for some reason, the credentials aren't sent out to a different user. You should probably add some error checks in too, just for your own sanity.
UPDATE
As you are getting an error with the woocommerce_created_customer action you might get better results listening for the woocommerce_new_customer_data filter.
class NewCustomerRegistration
{
private $credentials;
public function __construct()
{
// Use PHP_INT_MAX so that it is the last filter run on this data
// in case there are other filter changing the password, for example
add_filter(
'woocommerce_new_customer_data',
[$this, 'when_user_is_created'],
1,
PHP_INT_MAX
);
add_action('woocommerce_new_customer', [$this, 'when_customer_is_created']);
}
public function when_user_is_created($customerData)
{
$this->credentials = [
'email' => $customerData['user_email'],
'password' => $customerData['user_pass'],
];
return $customerData;
}
public function when_customer_is_created($customerId)
{
$customer = get_userdata($customerId);
/**
* Perform the required actions with collected data
*
* Email: $this->credentials['email']
* Password: $this->credentials['password']
* First Name: $customer->first_name
* Last Name: $customer->last_name
*/
}
}
In my Laravel application, a User can have a Profile which they or a user with privileges can update.
The relation for these two models is defined in this method:
/**
* Get the profile associated with this user
*/
public function profile()
{
return $this->hasOne(Profile::class, 'user_username', 'username');
}
This is the method for updating a user profile:
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param \App\Profile $profile
* #return \Illuminate\Http\Response
*/
public function update(UpdateProfile $request, User $user)
{
if ($user) {
// Only proceed if there is a logged in user
$profile = $user->profile;
// If there is no profile, create one for this user as they'll need one.
if (!empty(request()->get('background'))) {
$profile->background = clean($request->get('background'));
}
if (!empty(request()->get('skills'))) {
$profile->skills = clean($request->get('skills'));
}
if (!empty(request()->get('filepath'))) {
$profile->displayPicture = $request->get('filepath');
}
if (!empty(request()->get('linkedInUrl'))) {
$socialProfilesDecoded = json_decode($user->profile->socialProfiles, true);
$socialProfilesDecoded["LinkedIn"] = $request->get('linkedInUrl');
$profile->socialProfiles = json_encode($socialProfilesDecoded);
}
if (!empty(request()->get('twitterUrl'))) {
$socialProfilesDecoded = json_decode($user->profile->socialProfiles, true);
$socialProfilesDecoded["Twitter"] = $request->get('twitterUrl');
$profile->socialProfiles = json_encode($socialProfilesDecoded);
}
$user->profile()->save($profile);
return redirect()->back()->withSuccess('Your profile has been successfully updated');
}
}
The route for updating a profile is:
Route::post('profile/{user}', 'ProfileController#update');
It came to my attention that exposing the username presents a vulnerability as if you're able to grab the request with a web proxy you can just change the username and update another user's profile.
Without changing the URL could I put a Policy in place to check that:
The user has permission to update said profile
The profile being updated is the correct profile (and the request wasn't tampered with.
Or, should I change the URL and have a way to edit profiles in an admin area only?
Also, as a Profile is associated with a User, how could a privileged user access another user's profile?
Maybe a hidden input?
Update:
if ($request->is('admin/*')) {
//
}
Could I check if this matches the POST request?
Update 2
Added a simple check to ensure the logged in user had permissions to update a Profile.
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param \App\Profile $profile
* #return \Illuminate\Http\Response
*/
public function update(UpdateProfile $request, User $user)
{
// Check this user
if(auth()->user() == $user || auth()->user()->can('Approve user profile')){
if ($user) {
// Only proceed if there is a logged in user
$profile = $user->profile;
// If there is no profile, create one for this user as they'll need one.
if (!empty(request()->get('background'))) {
$profile->background = clean($request->get('background'));
}
if (!empty(request()->get('skills'))) {
$profile->skills = clean($request->get('skills'));
}
if (!empty(request()->get('filepath'))) {
$profile->displayPicture = $request->get('filepath');
}
if (!empty(request()->get('linkedInUrl'))) {
$socialProfilesDecoded = json_decode($user->profile->socialProfiles, true);
$socialProfilesDecoded["LinkedIn"] = $request->get('linkedInUrl');
$profile->socialProfiles = json_encode($socialProfilesDecoded);
}
if (!empty(request()->get('twitterUrl'))) {
$socialProfilesDecoded = json_decode($user->profile->socialProfiles, true);
$socialProfilesDecoded["Twitter"] = $request->get('twitterUrl');
$profile->socialProfiles = json_encode($socialProfilesDecoded);
}
$user->profile()->save($profile);
return redirect()->back()->withSuccess('Your profile has been successfully updated');
}
}
}
I was wondering how I could add a check during user login with Confide, to check if a user account is flagged as disabled?
In the Confide class there's the following function:
/**
* Attempt to log a user into the application with
* password and identity field(s), usually email or username.
*
* #param array $credentials
* #param bool $confirmed_only
* #param mixed $identity_columns
* #return boolean Success
*/
public function logAttempt( $credentials, $confirmed_only = false, $identity_columns = array() )
{
// If identity columns is not provided, use all columns of credentials
// except password and remember.
if(empty($identity_columns))
{
$identity_columns = array_diff(
array_keys($credentials),
array('password','remember')
);
}
// Check for throttle limit then log-in
if(! $this->reachedThrottleLimit( $credentials ) )
{
$user = $this->repo->getUserByIdentity($credentials, $identity_columns);
if(
$user &&
($user->confirmed || ! $confirmed_only ) &&
$this->app['hash']->check(
$credentials['password'],
$user->password
)
)
{
$remember = isset($credentials['remember']) ? $credentials['remember'] : false;
$this->app['auth']->login( $user, $remember );
return true;
}
}
$this->throttleCount( $credentials );
return false;
}
All I would really like to do is add a check for $user->disabled which is a field I created. Short of extending and registering a new service provider, does anyone know of another way of doing this?
I use Codeigniter framework + Tank_Auth registiration library. They work great but I just need to change register form a bit.
I want to generate username from email address instead of getting it from registeration form. I added a simple function to libraries/Tank_auth.php file. Here is my username generator function:
function _create_username_from_email($email)
{
$user = strstr($email, '#', true); // As of PHP 5.3.0
return $user;
}
Please let me know where I need to run my function and write it to database.
I will also need to remove username field from register form. So I need how I can pass form validation for username field in my controller.
I will be really happy if any of you can help me about these problem.
Thanks
At line 121 in application/models/tank_auth/users you have:
/**
* Create new user record
*
* #param array
* #param bool
* #return array
*/
function create_user($data, $activated = TRUE)
{
$data['created'] = date('Y-m-d H:i:s');
$data['activated'] = $activated ? 1 : 0;
if ($this->db->insert($this->table_name, $data)) {
$user_id = $this->db->insert_id();
if ($activated) $this->create_profile($user_id);
return array('user_id' => $user_id);
}
return NULL;
}
Just before the if ($this->db->insert($this->table_name, $data)) { insert:
$data['username'] = strstr($data['email'], '#', true);
P.S.
I hope you understand it, but just in case - if you have two or more users with same email's username part like john#hotmail.com and john#gmail.com they both will have the same username, which may lead to unexpected behavior.
I am new to Magento and PHP. I use the following line to get the email, which works fine except in the case a customer just registered. Any suggestions? Thanks.
$userEmail = Mage::getSingleton('customer/session')->getCustomer()->getEmail();
I assume that this code runs before the customer object data was saved propperly.
There is a line of code callled: in the OnePageCheckout and it does the following:
/**
* Involve new customer to system
*
* #return Mage_Checkout_Model_Type_Onepage
*/
protected function _involveNewCustomer()
{
$customer = $this->getQuote()->getCustomer();
if ($customer->isConfirmationRequired()) {
$customer->sendNewAccountEmail('confirmation', '', $this->getQuote()->getStoreId());
$url = Mage::helper('customer')->getEmailConfirmationUrl($customer->getEmail());
$this->getCustomerSession()->addSuccess(
Mage::helper('customer')->__('Account confirmation is required. Please, check your e-mail for confirmation link. To resend confirmation email please click here.', $url)
);
} else {
$customer->sendNewAccountEmail('registered', '', $this->getQuote()->getStoreId());
$this->getCustomerSession()->loginById($customer->getId());
}
return $this;
}
If the customer is just registering, not using the checkout process, then there is a different function using the request parameters like Anton said:
/app/code/core/Mage/Customer/Block/Form/Register.php
/**
* Restore entity data from session
* Entity and form code must be defined for the form
*
* #param Mage_Customer_Model_Form $form
* #return Mage_Customer_Block_Form_Register
*/
public function restoreSessionData(Mage_Customer_Model_Form $form, $scope = null)
{
if ($this->getFormData()->getCustomerData()) {
$request = $form->prepareRequest($this->getFormData()->getData());
$data = $form->extractData($request, $scope, false);
$form->restoreData($data);
}
return $this;
}
you can get it from request parameters directly?