What I am trying
I need to send a mail to a user when a file has been uploaded to that user. I'm using a custom developed plugin to achieve this. I'm using postman SMTP for sending mails.
The file is added as a post here. The problem is when I publish it sends around 80+ mails to the assigned user in which only 1 mail contains the correct information. Other mails are all blank with just static predefined mail content.
How to fix this?
Code
add_action('save_post', 'upf_save_post');
function upf_save_post($post_id, $post = null) {
global $post;
/* --- security verification --- */
if(!wp_verify_nonce($_POST['wp_upf_nonce'], plugin_basename(__FILE__)))
return $post_id;
if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return $post_id;
// if invalid $post object or post type is not 'userfile', return
if(!$post || get_post_type($post->ID) != 'userfile') return;
$user_info = get_userdata($_POST['upf_user']);
add_post_meta($post_id, 'upf_user', $user_info->user_login);
update_post_meta($post_id, 'upf_user', $user_info->user_login);
// Make sure the file array isn't empty
if(!empty($_FILES['upf_file']['name'])) {
// Setup the array of supported file types. In this case, it's just PDF.
$supported_types = array('application/pdf','image/png','image/jpg','image/jpeg','text/plain','text/html','application/msword','application/vnd.openxmlformats-officedocument.wordprocessingml.document','application/vnd.ms-excel','application/vnd.openxmlformats-officedocument.spreadsheetml.sheet','application/vnd.ms-powerpoint','application/vnd.openxmlformats-officedocument.presentationml.presentation',);
// Get the file type of the upload
$arr_file_type = wp_check_filetype(basename($_FILES['upf_file']['name']));
$uploaded_type = $arr_file_type['type'];
// Check if the type is supported. If not, throw an error.
if(in_array($uploaded_type, $supported_types)) {
$upf_file = get_post_meta($post_id, 'upf_file', true);
if ($upf_file) {
$upf_file_path = WP_CONTENT_DIR.'/userfiles/'.$upf_file['file'];
if (file_exists($upf_file_path)) unlink($upf_file_path);
}
// Use the WordPress API to upload the file
$upload = wp_handle_upload( $_FILES['upf_file'], array( 'test_form' => false ) );
if(isset($upload['error']) && $upload['error'] != 0) {
wp_die(__('There was an error uploading your file. The error is: ' . $upload['error'], 'user-private-files'));
} else {
// Update custom field
$upload['file'] = substr($upload['file'],stripos($upload['file'],'wp-content/userfiles/')+21);
add_post_meta($post_id, 'upf_file', $upload);
update_post_meta($post_id, 'upf_file', $upload);
} // end if/else
} else {
wp_die(__("The file type that you've uploaded is not supported.", 'user-private-files'));
} // end if/else
} // end if
if ($_POST['upf_notify'] == '1') {
if( get_post_meta($post_id, 'email_sent', 'true') != 'yes' ) {
$upf_file = get_post_meta($post_id, 'upf_file', true);
$email_subject = get_option('upf_email_subject');
$email_msg = get_option('upf_email_message');
$email_msg = str_replace('%blogname%', get_bloginfo('name'), $email_msg);
$email_msg = str_replace('%siteurl%', get_bloginfo('url'), $email_msg);
$email_msg = str_replace('%user_login%', $user_info->user_login, $email_msg);
$email_msg = str_replace('%filename%', basename($upf_file['file']), $email_msg);
$email_msg = str_replace('%download_url%', get_bloginfo('url').'/?upf=dl&id='.$post_id, $email_msg);
$cats = wp_get_post_terms($post_id, 'file_categories', array("fields" => "names"));
$email_msg = str_replace('%category%', implode(", ", $cats), $email_msg);
$headers[] ='From: "'.htmlspecialchars_decode(get_bloginfo('name'), ENT_QUOTES).'" <'.get_option('admin_email').'>';
wp_mail($user_info->user_email, $email_subject, $email_msg, $headers);
add_post_meta($post_id, 'email_sent', 'yes', true);
}
}
}
This may occur because before actually save post, WordPress itself fire save_post action to save post revision.
// If this is just a revision, don't send the email.
if ( wp_is_post_revision( $post_id ) )
return;
Wordpress fire this save_post action on every page status
like on revision, draft, publish, pending
you should check these condition inside your save_post action as per your working.
check the code here
https://codex.wordpress.org/Plugin_API/Action_Reference/save_post
so you should check
Related
I am trying to send out emails to my customers and allow them one click to reset passwords with their email pre-filled on the reset password page by URL /account/lost-password/?email=123#gmail.com
However, I am not sure how to make it right. Here is my code. Thanks!
add_action( 'template_redirect', 'set_custom_data_wc_session' );
function set_custom_data_wc_session () {
if ( isset( $_GET['email'] ) ) {
$em = isset( $_GET['email'] ) ? esc_attr( $_GET['email'] ) : '';
// Set the session data
WC()->session->set( 'custom_data', array( 'email' => $em ) );
}
}
add_filter( 'woocommerce_login_form' , 'prefill_login_form' );
function prefill_login_form ( $fields ) {
// Get the session data
$data = WC()->session->get('custom_data');
// Email
if( isset($data['email']) && ! empty($data['email']) )
$fields['user_login']['default'] = $data['email'];
return $fields;
}
I managed to do it by referencing this thread
Pre-fill Woocommerce login fields with URL variables saved in session
<?php
add_action('woocommerce_lostpassword_form','woocommerce_js_2');
function woocommerce_js_2()
{ // break out of php
?>
<script>
// Setup a document ready to run on initial load
jQuery(document).ready(function($) {
//var r = /[?|&](\w+)=(\w+)+/g; //matches against a kv pair a=b
var r = /[?|&](\w+)=([\w.-]+#[\w.-]+)/g;
var query = r.exec(window.location.href); //gets the first query from the url
while (query != null) {
//index 0=whole match, index 1=first group(key) index 2=second group(value)
$("input[name="+ query[1] +"]").attr("value",query[2]);
query = r.exec(window.location.href); //repeats to get next capture
}
});
</script>
<?php } // break back into php
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.
I've searched seemingly every relevant question on this but I'm stuck, as none of them address the particular case of uploads through XML RPC.
I want to conditionally change the Wordpress file upload directory, only if the file is coming in through an XML RPC call and only if the call is coming in from a particular user.
My approach is based on a combination of this Answer, this Answer and the Codex.
Here's what I tried with no luck:
add_filter( 'xmlrpc_methods', 'call_intercept1' );
function call_intercept1( $methods ) {
$methods[ 'metaWeblog.newMediaObject' ] = 'custom_upload1';
return $methods;}
function custom_upload1( $args ) {
global $wpdb;
$username = $this->escape( $args[1] );
$password = $this->escape( $args[2] );
$data = $args[3];
$name = sanitize_file_name( $data['name'] );
$type = $data['type'];
$bits = $data['bits'];
if ( !$user = $this->login($username, $password) )
return $this->error;
if ( $username = "XXX" ) {
add_filter('upload_dir', 'custom_upload_dir1');
}
$upload = wp_upload_bits($name, null, $bits);
if ( ! empty($upload['error']) ) {
/* translators: 1: file name, 2: error message */
$errorString = sprintf( __( 'Could not write file %1$s (%2$s).' ), $name, $upload['error'] );
return new IXR_Error( 500, $errorString );
}
return $upload;
}
function custom_upload_dir1( $param ){
$custom_dir = '/the-desired-directory';
$param['path'] = $param['path'] . $custom_dir;
$param['url'] = $param['url'] . $custom_dir;
error_log("path={$param['path']}");
error_log("url={$param['url']}");
error_log("subdir={$param['subdir']}");
error_log("basedir={$param['basedir']}");
error_log("baseurl={$param['baseurl']}");
error_log("error={$param['error']}");
return $param;
}
The file is being uploaded correctly, but the conditional directory change isn't happening.
Does someone know why that would be?
I was able to get this worked out, essentially using Ulf B's Custom Upload Dir as a model and simplifying it from there.
For anyone else facing the same problem, here's what works:
// XMLRPC Conditional Upload Directory
add_action('xmlrpc_call', 'redirect_xmlrpc_call');
function redirect_xmlrpc_call($call){
if($call !== 'metaWeblog.newMediaObject'){return;}
global $wp_xmlrpc_server;
$username = $wp_xmlrpc_server->message->params[1];
$data = $wp_xmlrpc_server->message->params[3];
if($username !== "XXX"){return;}
else {custom_pre_upload($data);}}
function custom_pre_upload($data){
add_filter('upload_dir', 'custom_upload_dir');
return $data;}
function custom_post_upload($fileinfo){
remove_filter('upload_dir', 'custom_upload_dir');
return $fileinfo;}
function custom_upload_dir($path){
if(!empty($path['error'])) { return $path; } //error; do nothing.
$customdir = '/' . 'your-directory-name';
$path['subdir'] = $customdir;
$path['path'] .= $customdir;
$path['url'] .= $customdir;
return $path;}
I am using add_action( 'after_setup_theme', 'custom_login' ); hook in one of my website for auto redirect user to his dashboard page.
Here is my code :---
function custom_login($username, $password='') {
$creds = array();
$creds['user_login'] = $username;
$creds['user_password'] = $password;
$creds['remember'] = true;
$user = wp_signon( $creds, false );
if ( is_wp_error($user) ){
echo $user->get_error_message();
}
}
// run it before the headers and cookies are sent
add_action( 'after_setup_theme', 'custom_login' );
Its working fine on old version, But now I have upgrade wordpress version and its creating problem with nonce.
Are you sure you want to do this?
Everytime this error display on the screen when I do anything like update plugin, theme and permalinks.
When I comment this code then website working fine except auto redirect functionality.
Here is my website url :- https://www.linearrecruitment.co.uk/
Please help me where I do mistake.
That's a normal behaviour - nonce is a token used by Wordpress to check the validity of the form in order to prevent CSRF attacks.
A valid login form in Wordpress should have an hidden input field generated with wp_nonce_field:
wp_nonce_field('my_login_form');
Then in the login function the token is checked with the wp_verify_nonce function:
if (!isset($_POST['my_login_form']) || !wp_verify_nonce($_POST['_wpnonce'], 'my_login_form')) {
die('Invalid form');
}
What you're trying to do (auto login) is done wrong as add_action doesn't send any parameter for the after_setup_theme hook, so your username is probably empty. I don't know how this could possibly work before, maybe it managed to log in somehow with an empty username.
I suggest you to declare some globals vars for your username and password, as it seems to be static inputs:
global $username, $password;
$username = 'my_login';
$password = 'my_password';
And then on the beginning of your function import those globals with:
global $username, $password;
So what about the nonce?
On the last versions of Wordpress, the check_admin_referer have changed a bit, from:
function check_admin_referer( $action = -1, $query_arg = '_wpnonce' ) {
if ( -1 == $action )
_doing_it_wrong( __FUNCTION__, __( 'You should specify a nonce action to be verified by using the first parameter.' ), '3.2' );
$adminurl = strtolower(admin_url());
$referer = strtolower(wp_get_referer());
$result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce($_REQUEST[$query_arg], $action) : false;
if ( !$result && !(-1 == $action && strpos($referer, $adminurl) === 0) ) {
wp_nonce_ays($action);
die();
}
do_action( 'check_admin_referer', $action, $result );
return $result;
}
To :
function check_admin_referer( $action = -1, $query_arg = '_wpnonce' ) {
if ( -1 == $action )
_doing_it_wrong( __FUNCTION__, __( 'You should specify a nonce action to be verified by using the first parameter.' ), '3.2' );
$adminurl = strtolower(admin_url());
$referer = strtolower(wp_get_referer());
$result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce($_REQUEST[$query_arg], $action) : false;
do_action( 'check_admin_referer', $action, $result );
if ( ! $result && ! ( -1 == $action && strpos( $referer, $adminurl ) === 0 ) ) {
wp_nonce_ays( $action );
die();
}
return $result;
}
As you can see they moved the check_admin_referer hook - now we can change the value of $result before the wp_nonce_ays function (the one that display the message you try to get rid of) as been called.
That mean we could add the following hook in the theme functions.php in order to force the nonce validation:
add_action( 'check_admin_referer', array('custom_check_admin_referer' ) );
function custom_check_admin_referer() {
return 1;
}
That should work around your problem, but you must be aware that this could possibly be a security issue - you maybe want to do more test in that function before returning 1.
I am having trouble with a form I created with gravityforms. This form's purpose is to grab the form's input, encrypt the password and write that data directly to a database. I have verified the database's username, password and IP.
The problem is that the form does submit, I can see the entry, but no data is written to the database. it just stucks with a loading circle next to the submit button.
Here is the code I use inside my functions.php file:
add_action("gform_after_submission_1", "create_account", 10, 2);
function create_account($entry, $form) {
define('mySQL_hostname', '<ip>'); //database IP
define('mySQL_database', '<database name>'); //database name
define('mySQL_username', '<user>'); //database user
define('mySQL_password', '<pass>'); //database password
$db_link = mysql_pconnect( mySQL_hostname, mySQL_username, mySQL_password )
or die( 'Error connecting to mysql<br><br>'.mysql_error() );
function l2j_encrypt($password) {
return base64_encode(pack("H*", sha1(utf8_encode($password))));
}
$str = l2j_encrypt($entry["2"]);
$user = $entry["1"];
$currdate = date('Y-m-d H:i:s');
$email = $entry["3"];
$db_select = mysql_select_db( mySQL_database, $db_link )
or die( 'Error connecting to Database<br><br>'.mysql_error() );
if ($user == '') { print'Incorrect UserID'; mysql_close(); }
else {
$db_add = mysql_query( "INSERT INTO `accounts` VALUES ('$user', '$str', '0', '0', '', '1', '$email', '$currate')" )
or die( 'Error: '.mysql_error() );
}
mysql_close();
}
Also, what's the deal with the 10,2 parameters? I couldn't find anything that explains those...
Note that the above code, when in a separate php file, combined with an html form, work just fine....
Any help?
P.S: Can anyone help me build a function that submit this data to an external php file? In case I cannot make this work....
After playing around with gravity for a bit, i managed to find a workaround.
add_action("gform_after_submission_6", "set_page_log", 10, 2);
function set_page_log($entry, $form){
function post_to_url($url, $data) {
$fields = '';
foreach($data as $key => $value) {
$fields .= $key . '=' . $value . '&';
}
rtrim($fields, '&');
$post = curl_init();
curl_setopt($post, CURLOPT_URL, $url);
curl_setopt($post, CURLOPT_POST, count($data));
curl_setopt($post, CURLOPT_POSTFIELDS, $fields);
curl_setopt($post, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($post);
curl_close($post);
}
if($form["id"] == 6){//checking if the correct form is being used or not (optional)
$data = array(
"item1" => $entry["2"],
"item2" => $entry["5"],
"item3" => $entry["4"]
);
post_to_url("http://www.example.com/post_data.php", $data);
//you can make changes to the data passed by gravity at the above url
}
}
I have tested the above code with Gravity 1.6 and WP 3.5.1.