I have a custom post type called "Booking" in WP travel plugin. I want it to fire an event when i change the status of that custom post type from 'pending' to 'booked'.
The event should send a confirmation email to the user in question.
I tried the following :
function show_alert_msg( $new_status, $old_status, $post ) {
if ( 'Booked' === $new_status && 'pending' !== $old_status && $post->post_type=='Booking' )
{
echo '<script>alert(Show message after transition to booked)</script>' ;
}else{
echo '<script>alert(failed)</script>' ;
}
}
add_action( 'transition_post_status', 'show_alert_msg', 10, 3 );
but whenever i change the status nothing happens.
what i am doing wrong? and how can I approach this correctly so that when the booking status changes from pending to Booked, the confirmation email is sent to the user ?
It's because there are several bugs in your code!
You're using WP travel plugin. This plugin register its custom post type as "itinerary-booking", but in your code, you're checking for a custom post type called "Booking" which doesn't exist, so that condition never returns true!
You could navigate to this path:
"your website folder > wp-content > plugins > wp-travel > inc"
and open up class-post-types.php file on line 126 you see this register_post_type( 'itinerary-booking', $args );
Also, you're using transition_post_status action hook which is used for the checking a post status. The status of pending and booked are custom post meta data and saved into the database under the wp_travel_booking_status name and have nothing to do with the post status itself! Which means it's totally different than what you're trying to do.
So, this filter hook transition_post_status is not responsible to pick up those statuses.
Also, when trying to debug/test your code, specially on transition_post_status and save_post hooks, do NOT use javascript alert, console.log and/or php echo, print_r, var_dump etc. because when you hit those hooks, printing, echoing, alerting won't work. Just use php die function which will stop the app and lets you know that you hit the hook.
Also capitalization matters! Make sure you're using the right capitalization for your values, for example, in this case, everything is lowercase. So keep an eye on that!
Now what can you do about it?
Well, you could change your hook to save_post action hook which means every time that you update your post, it'll fire!
You could change your conditional check to look for itinerary-booking custom post type.
Also you could use get_post_meta function, to check for your status change!
Now putting it all together, you could use the following code:
add_action( 'save_post', 'sending_email_confirmation_to_user');
function sending_email_confirmation_to_user( $post_id )
{
if ( 'itinerary-booking' == get_post_type( $post_id ) ){
$post_status_after_update = get_post_meta( $post_id, 'wp_travel_booking_status', true );
if( 'booked' === $post_status_after_update ){
die("Send your email here!");
} else {
die("your post status is not booked!");
}
}
}
Note:
I used die statement just to give you an example, so make sure to replace die("Send your email here!"); with your custom function that sends out emails!
Status of booked is lowercase, so don't change it to uppercase like the one you tried in your code! Otherwise it won't work!
When your post status is not "booked", you don't have to do anything, i used die("your post status is not booked!"); just to give you an example!
Update
When you use save_post hook, it runs every time you update your custom post data, BUT you do NOT want to send an email every single time. Right?
When you change the status from 'pending' to 'booked' you could save a meta data in the database so that you know you've already sent an email confirmation and you don't want to send another email. You could do that using update_post_meta function.
add_action( 'save_post', 'sending_email_confirmation_to_user');
function sending_email_confirmation_to_user( $post_id )
{
if ( 'itinerary-booking' == get_post_type( $post_id ) ){
$post_email_status = get_post_meta( $post_id, 'custom_confirmation_email', true );
$post_status_after_update = get_post_meta( $post_id, 'wp_travel_booking_status', true );
if( 'booked' === $post_status_after_update && empty( $post_email_status )){
$email_sent = update_post_meta( $post_id, 'custom_confirmation_email', 'sent-at-'. date( 'M_d_Y-H_i_s' ) );
die("Send your email here!");
}
}
}
Note:
This will make sure that you only send your email confirmation once!
If the email confirmation data is empty in the database, it'll send the email and update the value in the database and won't send extra emails.
Also, I've stored a meta data in your database called custom_confirmation_email and used 'sent-at-'. date('M_d_Y-H_i_s') as its value which looks like this: sent-at-Oct_01_2021-17_42_42 which is the date and time when the status changed from 'pending' to 'booked' for the first time.
All of the snippets and explanations have been fully tested and work!
Related
I implemented a function in my Wordpress admin panel, which is a checkbox. I like to send a email to that specific user, when I check the box or uncheck the box on his specific post and hit the save-button on the upper right corner.
When I check the box, a warning field appears on users post. When I uncheck it, the warning disappears. For now I worked with the get_post_meta() method.
I like to send a email to the user as a warning automatically, if I manually check the warning-box.
I have tried this but it did not work...
$warning = get_post_meta( $post->ID, 'warningbox', true );
if ($warning == 1) {
sendMailToUser();
}
I guess this is not the right solution, so how can I implement this function?
Thank you :)
Are you sure sendMailToUser() is defined, that's not a standard WordPress function. Either way, a custom function isn't really necessary there.
You'll want to hook into the save_post hook, check the value of the post_meta field, and then use the wp_mail() function to alert the post author. It almost sounds like using an AJAX function would be handier here, but that's also more complicated.
Something like this should be more than sufficient:
add_action( 'save_post', 'alert_author_warningbox', 99, 2 );
function alert_author_warningbox( $post_ID, $post ){
if( get_post_meta($post_ID, 'warningbox', true) == 1 ){
$to = get_the_author_meta( 'user_email', $post_ID );
$subject = sprintf( 'Warning Box enabled for "%s"', $post->post_title );
$message = 'The warning box for your post has been enabled. Please contact the admin to resolve this warning.';
wp_mail( $to, $subject, $message );
}
}
I try to redirect my users to a custom page after successfully submitting the lost password form. By default, users are redirected to the "my-account" page.
The method responsible for doing this redirect is called process_lost_password() and is located in plugins/woocommerce/includes/class-wc-form-handler.php and looks like follows:
/**
* Handle lost password form.
*/
public static function process_lost_password() {
if ( isset( $_POST['wc_reset_password'] ) && isset( $_POST['user_login'] ) && isset( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'lost_password' ) ) {
$success = WC_Shortcode_My_Account::retrieve_password();
// If successful, redirect to my account with query arg set.
if ( $success ) {
wp_redirect( add_query_arg( 'reset-link-sent', 'true', wc_get_account_endpoint_url( 'lost-password' ) ) );
exit;
}
}
}
Unfortunately, this method does not offer any action to hook into.
Is there a way to override this method or change the redirect link in any other way?
Since process_lost_password() is run as an 'wp_load' action
add_action( 'wp_loaded', array( __CLASS__, 'process_lost_password' ), 20 );
You simply need to add your own action with a higher priority
add_action( 'wp_loaded', 'your_handler', 19 );
I RESOLVED the issue by going under
WooCommerce
Emails****
Place your email in the box all the way to the bottom where it states From address because I am the administrator and Remove the admin email address.
I did a couple of dummy accounts and it work fine now all passwords work very well.
I created a page added the end points to /lost-password/ for my permalinks. Checked the custom header and checked the title boxes towards the middle of page and Published the page. That fixed the issue for me.
i need a hook for the moment when an admin updates a post. (Click on update button). After the post is successfully updated.
The reason is, i have to call a function to update something for another plugin.
Everything i tried so far, is not working.
add_action( 'save_post', 'wpse41912_save_post' );
add_action( 'edit_post', 'wpse41912_edit_post' );
add_action( 'transition_post_status', 'wpse41912_transition_post_status' );
add_filter( "edit_post_{$field}", 'filter_edit_post_field', 10, 2 );
add_action( 'admin_head-post.php', 'admin_head_post_editing' );
add_action( 'admin_head-post-new.php', 'admin_head_post_new' );
add_action( 'admin_head-edit.php', 'admin_head_post_listing' );
In Everything function i wrote this, and i didnt see the echo or the alert box.
echo "my_update_user_meta";
$text = "my_update_user_meta";
echo '<script type="text/javascript">alert("' . $text . '")</script>';
Edit: i was missing the 3,4th parameter.
My Code now
add_action( 'save_post', 'mmx_save_post_action', 10, 3 );
function mmx_save_post_action( $post_id, $post, $update ) {
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) { // keine Aktion bei Autosave
//autosave
}else{
//no autosave
if ( is_admin() && current_user_can( 'manage_options' ) ) {
//admin panel && permission ok
//call function
}
}
}
When a post is updated there are some hooks that are fired:
'pre_post_update' is an action fired just before the post is updated, the argument passed are 2: $post_ID and $data that is an array of all the other database colums of the post table
'transition_post_status' is an hook fired on update, and pass 3 arguments: $new_post_status, $old_post_status and $post (object).
Then, there are other 2 transition hooks fired, but they are dynamic named, it means that the effective action fired depends on the old and the new post status.
"{$old_status}_to_{$new_status}" and "{$new_status}_{$post->post_type}". First pass the only the post object as argument, the second pass the post id and the post object. Find documentation here.
'edit_post' that pass 2 arguments: $post_ID and $post (object)
'post_updated' that pass 3 arguments: $post_ID, $post_after (post object after the update), $post_before (post object before the update)
Another dynamic hook: "save_post_{$post->post_type}" that depends on post type, e.g. for standard posts is 'save_post_post' and for pages is 'save_post_page', this hook pass 3 arguments: $post_ID, $post (object) and $update that is a boolean (true or false) that is true when you perform an update, in fact this hook is fired also when a post is saved for first time.
'save_post' that is fired both on update and on first saving, and pass the same 3 arguments of the previous hook.
'save_post_{$post_type}' that is fired both on update and on first saving, and pass the same first 2 arguments of the previous hook.
Finally you have 'wp_insert_post', that is fired both on update and on first saving, and pass the same 3 arguments of the previous 2 hooks.
These hook are fired every time a post is updated, both via admin pages in backend and via when updated "manually" using wp_update_post or wp_insert_post functions.
When the post is updated using admin pages there are additional hooks fired, an example is 'update_post_redirect' or 'post_updated_messages'. (See this and this WPSE answers for usage examples).
Note that if you want make use of some hooks argument, that isn't the first, one you have to explicitly declare it in add_action call.
E.g. if you want to use the '$update' argument (that is the 3rd) of the 'save_post' hook you need to add 3 as $accepted_args param on add_action (see docs):
// if you don't add 3 as as 4th argument, this will not work as expected
add_action( 'save_post', 'my_save_post_function', 10, 3 );
function my_save_post_function( $post_ID, $post, $update ) {
$msg = 'Is this un update? ';
$msg .= $update ? 'Yes.' : 'No.';
wp_die( $msg );
}
Last note regard timing: you must be sure that add_action is called before the action is triggered, or it will do nothing.
E.g. this code:
wp_update_post( $post );
add_action( 'save_post', 'my_function', 10, 3 );
will do nothing, because the action is added after the hook is fired. Here is simple to recognize it, in real world code isn't always so.
Ok so I am building a woocommerce site for a client and they love it but the only issue is they need a customer number to come through with the email for all new orders. They are willing to go in and fill in this info for each user, but I cannot find out how to get this info to automatically send with the new order email.
I am using WP - Members plugin to add custom information to the users profile, and have created a field there called Customer # (option name: customer_number) I cannot figure how to get woocommerce to add this number to the email that is sent when they place the order (to the admin)
I have tried many different things, it seems like it should just be a hook but I dont know how to get the values or have not been able to figure this out yet in any way.
I have looked and looked and this is my last resort, my minimal understanding of php and hooks is probably my downfall here, so please be very clear if instructing me in that way.
I will not give up on this issue, so I hope someone can help!
We can adapt from my tutorial on customizing the checkout fields to display some extra info in the email:
function kia_display_email_order_user_meta( $order, $sent_to_admin, $plain_text ) {
$user_id = $order->customer_user;
if( ! empty( $user_id ) && ( $data = get_user_meta( $user_id, '_some_user_meta', true ) ) != '' ){
if( $plain_text ){
echo 'The user data for some field is ' . $data;
} else {
echo '<p>The user data for <strong>some field</strong> is ' . $data . '</p>';
}
}
}
add_action('woocommerce_email_customer_details', 'kia_display_email_order_user_meta', 30, 3 );
In this case we'll replace the get_post_meta() of my tutorial with get_user_meta().... and knowing that the user Id is stored in the $order->customer_id property of the $order object.
I am creating something for a client and I have a Class that I created with a Custom Post Type called 'PuSH Feeds' and when the user adds a new post and publishes it they can then click on one of two buttons that I have in the Custom Meta Box.
One button is for 'Subscribe' and the other for 'Unsubscribe'. I am using the save_post action hook and testing if the $_POST global has that 'pushfeed-subscribe' or 'pushfeed-unsubscribe' and then do what I need to do. However for some reason I have found that once I click on the subscribe on my local machine stops the script because it says it did 100 consecutive calls etc and I end up with loads of duplicate posts with no title.
What would be the best way to avoid this and is there a better hook I can use for these special custom actions I want to activate of subscribing to a feed (which goes into another class and performs the subscribe method)?
This is the markup I have for those two buttons I mentioned with is inside the Metabox
<input type="submit" class="button-secondary" name="pushfeed-subscribe" id="pushfeed-subscribe" value="Subscribe">
<input type="submit" class="button-secondary" name="pushfeed-unsubscribe" id="pushfeed-unsubscribe" value="Unsubscribe">
Then I have this for the action hook:
add_action( 'save_post', array( $this, 'pushfeed_save_post_meta' ) );
The actual hook is like this:
public function pushfeed_save_post_meta( $post_id ) {
// Bail if we're doing an auto save
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
// if our nonce isn't there, or we can't verify it, bail
if( !isset( $_POST['pushfeed-nonce-field'] ) || !wp_verify_nonce( $_POST['pushfeed-nonce-field'], basename( __FILE__ ) ) ) return;
// If Subsctiption ID is empty, generate a random long number and save it
if ( empty( $_POST['pushfeed-subscription-id'] ) ) {
$random_number = substr(number_format(time() * mt_rand(),0,'',''),0,10);
$pushfeed_subscription_id = $random_number . $post_id;
update_post_meta( $post_id, 'pushfeed-subscription-id', $pushfeed_subscription_id );
}
...
if ( isset( $_POST['pushfeed-subscribe'] ) || isset( $_POST['pushfeed-unsubscribe'] ) ) {
$subscription_domain = get_post_meta($post_id, 'pushfeed-domain', true);
$subscription_id = get_post_meta($post_id, 'pushfeed-subscription-id', true);
$subscription_feed_url = get_post_meta($post_id, 'pushfeed-feed-url', true);
$subscription_callback_url = $subscription_domain . '/pushfeed/' . $subscription_id;
$sub = PuSHSubscriber::instance($subscription_domain, $subscription_id, 'PuSHSubscription', new PuSHEnvironment());
if ( isset( $_POST['pushfeed-subscribe'] ) ) {
$sub->subscribe($subscription_feed_url, $subscription_callback_url);
} elseif ( isset( $_POST['pushfeed-unsubscribe'] ) ) {
$sub->unsubscribe($subscription_feed_url, $subscription_callback_url);
}
}
}
I am trying to find out why is it that the post is saving multiple duplicates with no title.
But above all I would like to know if there is a better action hook I can call for these two custom actions.
Update :
Hi everyone. I ended up using an Ajax request using the wordpress admin-ajax.php when clicking a button and then firing of the subscription method. Once that is done the subscription method will do a get request and if returns a 200 code then the method returns true to the Ajax.
The problem is probably caused by your use of a submit button.
Custom Meta Boxes are not intended to include submit buttons. The idea is that they contain form fields that get submitted when you click on the standard "Update" button. You can then save what is submitted in the save_post action hook.
Using a submit other than "Update" may be confusing WordPress and causing your problem.
I suggest that you change your Custom Meta Box to have a checkbox for Subscribe or a radio button for Subscribe/Unsubscribe that you can look at in the action hook.