Send Mail to Admin when User change profile - php

I am trying to create a function that when a user updates her/his profile, the admin would get a mail notification. Not the data stored in wp_users, I would like to know changes stored in wp_usermeta. There are actually quite a lot of metakeys created with Ultimate Member.
The E-Mail should only contain the changed value, and best would be if the old value would be shown too.
As I am using the UltimateMember plugin.
According to this site, I would need this to get started:
function action_um_after_user_account_updated( $get_current_user_id ) {
// make action magic happen here...
};
add_action( 'um_after_user_account_updated', 'action_um_after_user_account_updated', 10, 1 );
After a lot of searching and mostly based on this I came up with this:
function action_um_after_user_account_updated( $get_current_user_id, $prev_value) {
$key = 'name';
$user = get_user_meta( $user_id, $key, $single);
$single = true;
if($prev_value->$key != $user->$key) {
$admin_email = "admin#site.com";
$message .= sprintf( __( 'New Name is: %s' ), $user ). "\r\n\r\n";
$message .= sprintf( __( 'Old name was: %s' ), $prev_value ). "\r\n\r\n";
wp_mail( $admin_email, sprintf( __( '[DB] Name changed' ) ),$message );
}
};
// add the action
add_action( 'um_after_user_account_updated', 'action_um_after_user_account_updated', 10, 1 );
Well, it doesn't work at all. I don't know if I have a php code problem, or if the code is maybe out of date, but I can't get it to work.
I also included the pluggable.php which I need to use the wp_mail, as far as I know. (include ABSPATH . WPINC . '/pluggable.php';) in the headerfile of my theme (smartpress).
Wordpress-Version: 4.8.2
Ultimate Member Version: 1.3.88
PHP Version: 5.6
UPDATE:
I now made a plugin instead, which is kind of working. I receive a mail, and I get the values from the provided meta_keys. Now, I don't want to show every meta_value in the mail, only the ones that changed. Is there any way to store the previous values, just before the profile gets updated and compare against it or something?
Here is my current code:
function profile_update_name() {
$user_id = get_current_user_id();
$single = true;
$user_fnm = get_user_meta( $user_id, 'firstnamemother', $single);
$user_lnm = get_user_meta( $user_id, 'nachnamemother', $single);
$admin_email = "admin#site.com";
$message .= sprintf( __( $user_fnm .' '. $user_lnm . ' has updated the profile.')). "\r\n\r\n";
$message .= sprintf( __( 'New Name is: %s' ), $user_fnm .' '. $user_lnm ). "\r\n\r\n";
$message .= sprintf( __( 'Old name was: %s' ), $user_lnm ). "\r\n\r\n";
wp_mail( $admin_email, sprintf( __( '[DB] Name changed' ) ),$message );
};
// add the action
add_action( 'um_user_after_updating_profile', 'profile_update_name', 1, 10 );

I believe that you problem is located here: $user = get_user_meta( $user_id, $key, $single);
Some variables you are passing in are empty. The following should get you the proper user meta:
$user = get_user_meta( $get_current_user_id, $key, true);
Here is an example of how you can get the last name of a user from the Codex:
<?php
$user_id = 9;
$key = 'last_name';
$single = true;
$user_last = get_user_meta( $user_id, $key, $single );
echo '<p>The '. $key . ' value for user id ' . $user_id . ' is: ' . $user_last . '</p>';
?>
You should var_dump() the $user variable to see how it returns the values.
EDIT:
As your question got updated, the second paremeter of the function get_user_meta() is the meta key. A meta key in this case is the part of a user that you want to retrieve. For example the first name or last name. Change the following in your code:
<?php
$user_fnm = get_user_meta( $user_id, 'name'/*I am 90% sure this one is right*/, $single);
$user_lnm = get_user_meta( $user_id, 'last_name', $single);
?>
This should retrieve the result you want. All you need to do now, is echo or use __($yourvar) to print it on the screen.

Related

How to customize the upload image field of the woocommerce account?

I was trying to add an image field to the woocommerce account settings section so that users could upload their avatars.
With a bit of research here on stack I came across this question that worked and gave the solution to my problem: Add a profile picture (file upload) on My account > edit account in WooCommerce
However, other questions have arisen and I have thought about extending the question to try to improve the final result as I believe it is a very common situation.
So I hope someone can answer this.
Will the uploaded image not appear for the post comments section or woocommerce product reviews? Do we need to change the meta image for this? It would be very useful to be able to view the uploaded image anywhere on the site, including the comments and reviews section.
If the user wants to remove the image and go back to the default how can he do it? There is no remove image button. Is there a way to insert a button and remove the image uploaded ?
Is there a way to set upload limit? For example, uploaded images must be jpeg or png and must not exceed 1mb in size.
The biggest problem is the directory where the images are saved, can it be different from the default media library? Furthermore, when the user changes multiple images, the previous one is not deleted and will remain forever in the media library taking up space unnecessarily.
I believe the answer to these questions completes something that the woocommerce world lacks by default. This may be a standard solution for most users.
For convenience, I report the code of the previous question:
// Add field
function action_woocommerce_edit_account_form_start() {
?>
<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
<label for="image"><?php esc_html_e( 'Image', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="file" class="woocommerce-Input" name="image" accept="image/x-png,image/gif,image/jpeg">
</p>
<?php
}
add_action( 'woocommerce_edit_account_form_start', 'action_woocommerce_edit_account_form_start' );
// Validate
function action_woocommerce_save_account_details_errors( $args ){
if ( isset($_POST['image']) && empty($_POST['image']) ) {
$args->add( 'image_error', __( 'Please provide a valid image', 'woocommerce' ) );
}
}
add_action( 'woocommerce_save_account_details_errors','action_woocommerce_save_account_details_errors', 10, 1 );
// Save
function action_woocommerce_save_account_details( $user_id ) {
if ( isset( $_FILES['image'] ) ) {
require_once( ABSPATH . 'wp-admin/includes/image.php' );
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );
$attachment_id = media_handle_upload( 'image', 0 );
if ( is_wp_error( $attachment_id ) ) {
update_user_meta( $user_id, 'image', $_FILES['image'] . ": " . $attachment_id->get_error_message() );
} else {
update_user_meta( $user_id, 'image', $attachment_id );
}
}
}
add_action( 'woocommerce_save_account_details', 'action_woocommerce_save_account_details', 10, 1 );
// Add enctype to form to allow image upload
function action_woocommerce_edit_account_form_tag() {
echo 'enctype="multipart/form-data"';
}
add_action( 'woocommerce_edit_account_form_tag', 'action_woocommerce_edit_account_form_tag' );
To display the image (can be used anywhere, provided you adjust the desired hook)
// Display
function action_woocommerce_edit_account_form() {
// Get current user id
$user_id = get_current_user_id();
// Get attachment id
$attachment_id = get_user_meta( $user_id, 'image', true );
// True
if ( $attachment_id ) {
$original_image_url = wp_get_attachment_url( $attachment_id );
// Display Image instead of URL
echo wp_get_attachment_image( $attachment_id, 'full');
}
}
add_action( 'woocommerce_edit_account_form', 'action_woocommerce_edit_account_form' );
// Save
function action_woocommerce_save_account_details( $user_id ) {
if ( isset( $_FILES['image'] ) ) {
require_once( ABSPATH . 'wp-admin/includes/image.php' );
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );
function wp_set_custom_upload_folder($uploads) {
$uploads['path'] = $uploads['basedir'] . '/custom-folder';
$uploads['url'] = $uploads['baseurl'] . '/custom-folder';
if (!file_exists($uploads['path'])) {
mkdir($uploads['path'], 0755, true);
}
return $uploads;
}
add_filter('upload_dir', 'wp_set_custom_upload_folder');
$attachment_id = media_handle_upload( 'image', 0 );
if ( is_wp_error( $attachment_id ) ) {
update_user_meta( $user_id, 'image', $_FILES['image'] . ": " . $attachment_id->get_error_message() );
} else {
$old_attachment_id = get_user_meta( $user_id, 'image', true );
wp_delete_attachment($old_attachment_id);
update_user_meta( $user_id, 'image', $attachment_id );
}
}
}
add_action( 'woocommerce_save_account_details', 'action_woocommerce_save_account_details', 10, 1 );
Set custom upload directory for profile image uploads
// Display function
function action_woocommerce_edit_account_form() {
// Get current user id
$user_id = get_current_user_id();
// Get attachment id
$attachment_id = get_user_meta($user_id, 'image', true);
// True
if ($attachment_id) {
$original_image_url = wp_get_attachment_url($attachment_id);
// Display Image instead of URL
echo wp_get_attachment_image($attachment_id, 'full');
if (isset($_GET['rm_profile_image_id'])) {
if ($attachment_id == $_GET['rm_profile_image_id']) {
wp_delete_attachment($attachment_id);
delete_user_meta($user_id, 'image');
?> <script>
window.location='<?php echo wc_get_account_endpoint_url('edit-account') ?>';
</script>
<?php
exit();
}
} else {
echo '<a href=' . wc_get_account_endpoint_url('edit-account') . '?rm_profile_image_id=' . $attachment_id . '> ' . __('Remove') . ' </a>';
}
}
}
When I have some free time I want to work on these issues. I'm not very good with codes I'm just a fan, but with study, research and practice I hope to make my contribution to this topic.
I publish this answer to update it every time I find a new solution. I'm sure someone can offer more efficient solutions, so corrections and answers that improve the topic are welcome.
Solution to problem n1 - Set the uploaded image anywhere on the site
Set the get_avatar filter (responsible for displaying the avatar in the comments section and other section of website) and assign it the url stored in the image meta_key.
add_filter( 'get_avatar', 'my_custom_avatar', 10, 6 );
function my_custom_avatar( $avatar, $id_or_email, $size, $default, $alt, $args ) {
// What is the custom image field's meta key?
// Set this value to match the meta key of your custom image field.
$meta_key = "image";
// Nothing really to change below here, unless
// you want to change the <img> tag HTML.
$user = false;
if ( is_numeric( $id_or_email ) ) {
$user = get_user_by( 'id' , (int)$id_or_email );
}
elseif ( is_object( $id_or_email ) ) {
if ( ! empty( $id_or_email->user_id ) ) {
$id = (int)$id_or_email->user_id;
$user = get_user_by( 'id' , $id );
}
} else {
$user = get_user_by( 'email', $id_or_email );
}
if ( $user && is_object( $user ) ) {
$post_id = get_user_meta( $user->ID, $meta_key, true );
if ( $post_id ) {
$attachment_url = wp_get_attachment_url( $post_id );
// HTML for the avatar <img> tag. This is WP default.
$avatar = wp_get_attachment_image($post_id, $size = array('50', '50'));
}
}
return $avatar;
}
Solution to problem n3 - Set a size limit for files
Thanks to this question Limit the size of a file upload (html input element) I found the solution to limit the file size in bytes. So here's what I did:
I assigned the input type file the id file
<input id="file" type="file" class="woocommerce-Input" name="image" accept="image/x-png,image/gif,image/jpeg">
I then applied the script below
/* Limit File Size for Avatar Upload (size in bytes) */
var uploadField = document.getElementById("file");
uploadField.onchange = function() {
// Put size in Bytes
if(this.files[0].size > 100000){
alert("File is too big!");
this.value = "";
};
};
The code provided by #mujuonly looks promising, however, please take the following into consideration:
Add a remove_filter after the else block in 1st code. Else all the website uploads will happen in that directory.
To do so, use:
remove_filter('upload_dir', 'wp_set_custom_upload_folder');
after else block.
2nd code should check if the user meta was deleted successfully or not. The line delete_user_meta($user_id, 'image'); should be wrapped in if condition like so:
if (delete_user_meta($user_id, 'image')){
wp_delete_attachment($attachment_id);
}
This way you don't delete the image first and make it unavailable for failed delete_user_meta.

how to handel submitted gravity form which contains singel file

i created a simple gravity form (id = 11) which contains 2 fields:
text field type (name = "my_name")
fileupload type (i could't set the name for it)
and there is the code i want to use for handel this form after submitation. how to change this snippet for handeling submited file?
Please suppose I have to do the manual handling of the form myself
$input_1 = $_POST['myname'];
//how to get sbmitted file?
//$file = ?
$array_of_inputs = array("input_1" => $input_1 , "file_name" => $file);
$gravity_submit_result = submit_in_gravity_form(11 , $array_of_inputs , $api_key , $private_key ,$web_url);
if ($gravity_submit_result){
$response['message'] = $body['response'];
$response['status'] = 'ok';
}
else{
$response['status'] = false;
}
exit(json_encode($response));}
this page contains my gravity form
For solve this issue you can follow this code
add_action( 'gform_after_submission', 'set_post_content', 10, 2 );
function set_post_content( $entry, $form ) {
//if the Advanced Post Creation add-on is used, more than one post may be created for a form submission
//the post ids are stored as an array in the entry meta
$created_posts = gform_get_meta( $entry['id'], 'gravityformsadvancedpostcreation_post_id' );
foreach ( $created_posts as $post )
{
$post_id = $post['post_id'];
$post = get_post( $post_id );
require_once( ABSPATH . 'wp-admin/includes/image.php' );
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );
$attach_id = media_handle_upload('file', $post_id);
if (is_numeric($attach_id)) {
update_option('option_image', $attach_id);
update_post_meta($post_id, '_my_file_upload', $attach_id);
}
update_post_meta($post_id, 'myname', $_POST['myname'];);
}
}

Wordpress get post field

I am overriding the admin email notification template in WooCommerce and when the order transaction is successful I want to add the transaction id in the email.
I tried $order->get_transaction_id() as explained here in the admin email template, but it returns an empty result.
I then tried this in the admin email template:
do_action('getOrderTransactionID', $order->id);
And in my theme's functions.php I added this but this function doesn't return anything either.
add_action('getOrderTransactionID', 'getOrderTransactionIDForEmail');
function getOrderTransactionIDForEmail($orderId){
echo get_metadata('post', $orderId, '_transaction_id', true);
//get_post_data doesn't return anything either
//get_post_meta( $orderId, '_transaction_id', true);
}
In the wp_postmeta table, the _transaction_id meta key is saved after each successful transaction. Why then am I unable to retrieve the _transaction_id which is already in the database?
What gateway are you using? If you don't see _transaction_id then you need to save the returned transaction_id manually in your gateway plugin. Check out this page
Try saving transaction id in your payment gateway file, then try to see if it displays when you do var_dump(get_post_custom($order->id));
add_post_meta( $order->id, '_transaction_id', YOUR_TRANSACTION_ID, true );
The following is an example of how to add data to email templates using existing hooks.
function kia_display_email_order_meta( $order, $sent_to_admin, $plain_text ) {
$some_field = get_post_meta( $order->id, '_some_field', true ),
$another_field = get_post_meta( $order->id, '_another_field', true ),
if( $plain_text ){
echo 'The value for some field is ' . $some_field . ' while the value of another field is ' . $another_field;
} else {
echo '<p>The value for <strong>some field</strong> is ' . $some_field. ' while the value of <strong>another field</strong> is ' . $another_field;</p>;
}
}
add_action( 'woocommerce_email_order_meta', 'kia_display_email_order_meta', 30, 3 );

Wordpress function advice - is this possible to target a specific function and execute another function after it?

Ok... so working on a theme designed by Astoundify... which although beautiful has been disgustingly made.
Also using WP Job Manager.
Have created a new custom field, 'fax'. Want fax to display after the phone number. Astoundify has nicely made this display on the theme using a widget - making the WP Job Manager hooks completely useless.
What i need to do is get that fax number to display immediately after phone. Is this possible to do with the functions file so that i don't have to modify the core files?
The following is the code which is outputting the phone number:
public static function the_phone() {
global $post;
$phone = $post->_phone;
if ( ! $phone ) {
return;
}
?>
<div class="job_listing-phone">
<span itemprop="telephone"><a href="tel:<?php echo esc_attr( preg_replace( "/[^0-9,.]/", '', $phone ) ); ?>"><?php echo
esc_attr( $phone ); ?></a></span>
</div>
<?php
}
And i am trying to output the fax using the following:
add_action( 'single_job_listing_start', 'display_fax_number_data', 50 );
function display_fax_number_data() {
global $post;
$fax = get_post_meta( $post->ID, '_fax', true );
if ( $fax ) {
echo '<li>' . __( 'Fax:' ) . ' ' . $fax . '</li>';
}
}
And its working... just not in the right place.
Have lost a day trying to do something that should have been so simple.
Any help appreciated.

Wordpress: Don't manage to retrieve author's name from php function

I'm creating a function that sends an email to a mailing list when a post is published on my WordPress blog.
function announce_post($post_id){
$email_address = 'address.of#the-mailing.list';
$subject = "New Post: " . get_the_title($post_id);
$body = "Hi,\r\n\r\n" .
"SOMEONE has just published the article \"" .
get_the_title($post_id) . "\" on \"BLOG TITLE\".\r\n\r\n" .
"You can read it at " . get_permalink($post_id) . "\r\n" .
"or visit BLOG_ADDRESS.\r\n\r\n" .
"Best wishes\r\n" .
"The Publisher";
if (wp_mail($email_address, $subject, $body, "From: \"BLOG TITLE\" <address.of#the-blog>")) { }
}
add_action('publish_post','announce_post');
As it is the function works well, but of course I would replace the SOMEONE with the actual post's author name. And I don't manage to retrieve that.
Neither get_the_author($post_id), get_post_meta($post_id, 'author_name', true) nor anything else I tried and can't recall worked. Everything just returned "".
So what is the correct way to retrieve the post author's name, given a post id?
get_the_author() is a (perhaps misleading) function that is intended for use in the loop. It's only parameter is now deprecated. It's also worth noting that author data is not stored as post meta, so any get_post_meta attempts will be in vain.
You should in fact use get_the_author_meta( 'display_name', $author_id ). I would suggest accepting the second argument in your hook, which is the $post object, to obtain the author ID:
function announce_post( $post_id, $post ) {
$name = get_the_author_meta( 'display_name', $post->post_author );
}
add_action( 'publish_post','announce_post', 10, 2 );

Categories