Wordpress is executing URL in code when called via wp_mail() - php

I have written a custom plugin (that creates a custom post type) and allows any user to submit a new post from a form on my website. To prevent bots, I have setup an e-mail confirmation code which they must click, where this changes the post status from Draft to Published.
Unfortunately the wp_mail() code shown below seems to be executing this confirmation URL automatically. As soon as the post is submitted, it is set to Draft until it reaches this code, and then it automatically publishes.
Removing this block however makes everything work as expected. Does anyone have any idea as to the reason and how to fix it?
$confirm_url = site_url(). '/verification?id=' . $post_id . '&hash=' . $hash;
// Send a verification e-mail to the user to confirm publication
$subject = 'Please confirm your Slicer Profile submission';
$body = $confirm_url;
wp_mail( $profile_email, $subject, $body );

This has been resolved, wanted to share the solution for anyone else that may stumble into this themselves. The site_url() was stored in its own variable and the forward slash in the URL string was not properly escaped, which seemed to have been causing the issue.
This has now been updated to the following and works perfect.
$site_url = site_url();
$confirm_url = $site_url. '\/verification?id=' . $post_id . '&hash=' . $hash;
// Send a verification e-mail to the user to confirm publication
$subject = 'Please confirm your Slicer Profile submission';
$body = $confirm_url;
wp_mail( $profile_email, $subject, $body );

Related

WordPress: I need to send users a notification when their role is changed, my code snippet doesn't work

I'm building a members style site using WordPress. When a user registers their default role is "subscriber" once we manually approve their account we change the user role to "private_event_member", we need to send the user an email to tell them we have changed their role. I found the following code snippet and added it to the functions.php file
function user_role_update( $user_id, $new_role ) {
$site_url = get_bloginfo('wpurl');
$user_info = get_userdata( $user_id );
$to = $user_info->user_email;
$subject = "Role changed: ".$site_url."";
$message = "Hello " .$user_info->display_name . " your role has changed on ".$site_url.", congratulations you are now an " . $new_role;
wp_mail($to, $subject, $message);
}
add_action( 'set_user_role', 'user_role_update', 10, 2);
This failed to send the email as expected. So to be sure I decided to install a plugin called WP Mail Log and then also WP Mail SMTP, I configured the Sendblue SMTP option. I've tested this and all other emails like for example user registration notifications and new orders are being sent and recorded successfully in the logs, these are being received. The above mentioned code however seems to do nothing.
This seems to be a widely used piece of code that should work so can anyone explain to me why this snippet behaves differently from other mail on the server? It doesn't even appear in the sending logs so as far as I can see it's not doing anything at all. Has the set_user_role action I'm hooking into changed? What could be the cause?
Any help much appreciate!
You should use profile_update hook for this. Read more here - https://developer.wordpress.org/reference/hooks/profile_update/
function notify_user_on_role_change($user_id,$old_user_data,$userdata) {
// Getting role before update
foreach($old_user_data->roles as $role):
$old_role = $role;
endforeach;
// error_log(print_r($userdata,true)); // debug
//If we change role send email
if($old_role != $userdata['role']):
$user_info = get_userdata( $user_id );
$to = $user_info->user_email;
$subject = "Profile Updated";
$message = "Hello, your user role is changed to ".$userdata['role']."";
wp_mail( $to, $subject, $message);
endif;
}
add_action('profile_update','notify_user_on_role_change',10,3);
Send notification only if you change to specific user role
function notify_user_on_role_change($user_id,$old_user_data,$userdata) {
// Getting role before update
foreach($old_user_data->roles as $role):
$old_role = $role;
endforeach;
// error_log(print_r($old_role,true)); // debug
//If we change role send email
if($old_role != 'private_event_member' && $userdata['role'] == 'private_event_member'):
$user_info = get_userdata( $user_id );
$to = $user_info->user_email;
$subject = "Profile Updated";
$message = "Hello, your user role is changed to ".$userdata['role']."";
wp_mail( $to, $subject, $message);
endif;
}
add_action('profile_update','notify_user_on_role_change',10,3);

success.php in my first contact form plugin results in page not found

UPDATE: sorry, thanks for the solutions offered... not really clear how to implement, I think ive not been too clear... if I can understand how to implement the solutions thatd be neat...
Ive also successfully managed to get code working to create a new database table and insert test data but ommited that so its not so complex....
I REALLY want to be able to...
display some content that I can put in success.php (or else where) when the message is sent successfully
that content would say Message Sent - YAY! and then Id like to be able to add, exisiting wp content - some services or products you might be interested in and display them on that same success result page after the message is sent...
maybe there is a better way to redirect users after the message is sent...
then....I also need to save the form data (not yet done) to the new table that I have created (got the table created via plugin), and then display a table of all form submission records in admin panel (not done)
I replaced the content of my main.php file (the plugin's main php file in plugin-name root.
<?php
/** template info etc...
**/
// Find all .php files in the includes dir of my plug in folder.
foreach ( glob( plugin_dir_path( __FILE__ ) . "includes/*.php" ) as $file ) {
include_once $file;
}
?>
and all my files except the main one (which is in the plugin root) are in plugins/plugin-name/includes and are being found - YAY
so my includes/webform.php displays the form nicely it sends an email but I can't get this error or success message via success.php or error.php thing to work.
includes/success.php now looks like this... as per DK's suggestion
<?Php
$Errors = implode(' ', $_SESSION['errMsg']);
echo $Errors; ?>
includes/webform.php now looks like this...
<?php
function d6s_opp_html_form() {
echo '<form action="' . esc_url( $_SERVER['REQUEST_URI'] ) . '" method="post">';
//Form action page is the current url. the form is called by a shortcode that will run functions that are written within this plugin's files, they can be in different files in different folders within the plug in because we have told the plug in to load them in the main plug in file.php horray thay is working..
// other form fields removed to shorten this stakoverflow post
echo '<p>';
echo 'Your Name* <br />';
echo '<input type="text" name="d6s-opp-name" pattern="[a-zA-Z0-9 ]+" value="' . ( isset( $_POST["d6s-opp-name"] ) ? esc_attr( $_POST["d6s-opp-name"] ) : '' ) . '" size="40" placeholder="First & Last name" required />';
// Now using required - is that better than having to check if not empty in success or fail bit????
echo '<p><input type="submit" name="d6s-submitted" value="Send"/></p>';
echo '</form>';
}
//Short code function is here and works GREAT
Then below that in the same file this is the function i figured DK meant that I should put the first part of his solution 1
I Guess this is where I have it wrong still
function deliver_opp_mail() {
// if the submit button is clicked, send the email
if ( isset( $_POST['d6s-submitted'] ) ) {
//sanitise form values so that form data is readable... eg/ if users enter code/script or formatting symbols, it is not missinterpretted as code and is seen as all text.
$name = sanitize_text_field( $_POST["d6s-opp-name"] );
$email = sanitize_email( $_POST["d6s-opp-email"] );
$messagesubject = sanitize_text_field( $_POST["d6s-opp-subject"] );
$messagecontent = esc_textarea( $_POST["d6s-opp-message"] );
$phone = ( $_POST["d6s-opp-phone"] );
// Would like to consider calling form values via global Variables.
$subject = "NEW OPPURTUNITY: $messagesubject";
$d6sdir = plugin_dir_path( __FILE__ );
//Create the Email Body Message using free text and data from the form.
$message = "New Message From: $name \n MESSAGE: $messagecontent \n Return Email: $email \n Return Phone $phone ";
// get the blog administrator's email address, form data is emailed to this email address.
$to = get_option( 'admin_email' );
// Look into setting a to: Email address in WP Admin Console.
$headers = "From: $name <$email>" . "\r\n";
if ( wp_mail( $to, $subject, $message, $headers ) ) {
//maybe this is in the wrong spot, or perhaps this is not the solution I need, but I have tried this in a few different places and can't get it to work..
$Msg = array(
"You have an error",
"Your mail sent succesfully"
);
$_SESSION['errMsg'] = $Msg;
//this take the user to www.mydomain.com/.....wp-content/plugins/my-plugin/includes/success.php - the file is there, but WP theme not found is displayed.
header("Location: $d6sdir/success.php");
exit;
}
}
}
?>
*Dont want to display a message above the form on success or error... future plans for workflow need to take users to a page with no form and other content after they hit submit.
*also using error reporting - seems like something happen or flashes up before the not found from the theme bit is displayed and no other error are reported...
<?Php error_reporting(E_ALL); ini_set('display_errors', 1);
************************** FROM INITAL POST....
Really keen to learn. First post, thanks for help
Purpose of plug in: Create a plugin that I can eventually build into a custom CRM tool for my small business and Learn to code.
*Why is this so not simple...
Solution 1 passing messages to success.php
$Msg = array(
"You have an error",
"Your mail sent succesfully"
);
$_SESSION['errMsg'] = $Msg;
success.php
$Errors = implode(' ', $_SESSION['errMsg']);
echo $Errors;
Solution 2 :
$_SESSION["errMsg"] = "Your mail sent succesfully";
if(isset($_SESSION['errMsg']) AND !empty($_SESSION['errMsg']) ):
echo "<div class='alert danger'>".$_SESSION['errMsg']."</div>";
endif;
Not found solution :
You can use $_SERVER['DOCUMENT_ROOT']; to find root D:/wamp/www
and then full url to page like so :
echo $_SERVER['DOCUMENT_ROOT']."/yourFolder/test.php";
output :D:/wamp/www/yourFolder/test.php
Note : will be nice if you use exit(); right after header("Location:");

wp_mail() - Sending 'file' input type from form as attachment

I have shortcode that creates and validates a form in my fucntions.php file. After the form is submitted and validated, the data is then stored in SESSION variables. The SESSION variables are used to carry the information to a custom PHP template page. This page emails the form data using wp_mail() and displays a thank you note.
My issue is that the form has a 'file' input type for an image upload. I have it validated correctly, but transferring the uploaded image and then emailing it as an '$attachments" in the wp_mail() function is something I am struggling with.
Also I know I should save the uploaded image in a temp folder instead of storing it in a SESSION variable. And then I will just have to delete the image after the email is sent.
My question is HOW? The code for all of this is very long so here are the short and sweet versions:
functions.php (in a shortcode function)
<?php
$file = "";
$fileErr = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
//file upload is required, make sure its not empty
if(empty($_FILES['pmFile'])){
$fileErr = "This is required!";
}
else{
$file = $_FILES['pmFile'];//I validate here, but lets just say its OK
}
//If the error message is empty, store data in SESSION variables, and
//uploaded file in temp folder + redirect to thank you page
if(empty($fileErr)){
//HOW DO I SAVE THE FILE TEMPORARILY FOR USE ON THE NEXT PAGE???
wp_redirect( '../wp-content/themes/rest of the path/thankYouPage.php' );
exit();
}else{ /*display errors*/}
}
//down here is where I wrote the code for the form. YES method=post, YES I
//included enctype="multipart/form-data, YES the file input name is in fact
//'pmFile'.
?>
thankYouPage.php
//initial page stuff
//start email setup
$to = 'XXXXX#gmail.com';
$email_from = 'XXXXX#gmail.com';
$email_subject = "New Price Match Request";
$email_body = "I display the html and data here";
//for attachments
//HOW DO I PULL THAT UPLOADED FILE FROM THE TEMP FOLDER AND SEND IT AS AN ATTACHMENT?
$attachments = (the file in temp folder);
//NOW HOW TO I DELETE IT FROM THE TEMP FOLDER
$headers = "From: $email_from \r\n";
$headers .= "Reply-To: $email \r\n"; //$email is a SESSION variable pulled from before
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
//set to html
add_filter('wp_mail_content_type',create_function('', 'return "text/html"; '));
//send
wp_mail( $to, $email_subject, $email_body, $headers, $attachments );
// Reset content-type to avoid conflicts
remove_filter( 'wp_mail_content_type', 'wpdocs_set_html_mail_content_type' );
I know a lot of the code it removed, but email works for all of the other information in the form being transferred by SESSION variables. I really just need to know how to transfer this uploaded file and email it. Thanks!
If I understood correctly...
For uploading file from temp folder use move_uploaded_file or wp_handle_upload.
Then attach file to the mail $attachments = array( WP_CONTENT_DIR . '/uploads/file.txt' );
Send mail and delete with unlink.
I would just use PHPMailer, its pretty easy and has a good documentation, sending an attachment is also easy with that.

Adding user meta values to Wordpress admin emails

When a new user registers on our website, they are required to fill out their company information. This information is stored in the _usermeta table with the meta_key 'company'.
All I want to do is include this information in the notification email that Wordpress sends to the site administrator. I have had some luck manipulating pluggables.php (where the default email code is located), but I can't get any meta values to send in the email.
Here is my current code:
function wp_new_user_notification($user_id, $plaintext_pass = '') {
$user = get_userdata( $user_id );
$user_meta = get_user_meta( $user_id );
$company = $user_meta['company'][0];
// The blogname option is escaped with esc_html on the way into the database in sanitize_option
// we want to reverse this for the plain text arena of emails.
$blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
$message = sprintf(__('New user registration on your site %s:'), $blogname) . "\r\n\r\n";
$message .= sprintf(__('Name: %s'), $user->display_name) . "\r\n\r\n";
$message .= sprintf(__('E-mail: %s'), $user->user_email) . "\r\n\r\n";
$message .= sprintf(__('Company: %s'), $company) . "\r\n";
#wp_mail(get_option('admin_email'), sprintf(__('[%s] New User Registration'), $blogname), $message);
The code outputs:
New user registration on your site mywebsite
Name: firstname lastname
E-mail: email#example.com
Company:
I have included get_user_meta() and get_metadata() but the value is always blank.
Any help is greatly appreciated.
I figured out the issue. The plugin I use to create new users (profile press) was posting the new user, triggering wp_new_user_notification, THEN adding custom values to the meta table. I moved the meta table function above wp_new_user_notification and the data is transferring as expected. Should anyone else run into this issue, here is how to solve it:
In wp-includes/pluggable.php, the following works as expected:
$company = get_user_meta( $user_id, 'company', true );
$message .= sprintf(__('Company: %s'), $company) . "\r\n";
As for profile press, navigate to wp-content/plugins/profilepress/classes/class-registration-form-auth.php and put:
// register custom profile field
if ( ! is_wp_error($user_id)) {
.
//truncated
.
do_action('pp_after_custom_field_update', $key, $value, $user_id, 'registration');
}
}
above:
if (is_int($user_id) && 'enable' == $new_user_notification) {
wp_new_user_notification($user_id, null, 'admin');
}
Hope this helps anyone else who has similar issues. Special thanks to #RaunakGupta for pointing me in the direction and credit to profile press for their code.

Send thank you email to every user creating an article in MediaWiki

I want my MediaWiki to send a 'Thank You' mail to the author when he creates a new article.
Is any extension available for this method?
Alternatively: I am creating article from a special page. So it is possible to add my own extension and write an email script. But I am confused how to get the email ID of the author.
Use the UserMailer and MailAddress classes:
global $wgPasswordSender, $wgPasswordSenderName;
$from = new MailAddress( $wgPasswordSender, $wgPasswordSenderName );
$to = new MailAddress( $user );
$subject = "Thank you!";
$text = "This is a test. Blah blah blah...";
$status = UserMailer::send( $to, $from, $subject, $text );
if ( $status->isGood() ) {
// Great, it worked!
} else {
// Something went wrong, deal with it...
// The $status object will have more information.
}
The MailAddress constructor takes either a User object or an address and a name. $wgPasswordSender is the default e-mail address used by MediaWiki for sending password reset e-mails and other such things; you've hopefully configured it in your LocalSetting.php.

Categories