Attempting to change the title of the thank you page based on specific order statuses, by combining a filter and action as follows:
add_action( 'woocommerce_thankyou', 'order_thank_you_status' );
function order_thank_you_status( $order_id ){
// Get an instance of the `WC_Order` Object
$order = wc_get_order( $order_id );
// Get the order number
$order_number = $order->get_order_number();
// Get the order status name
$status_name = wc_get_order_status_name( $order->get_status() );
// Get the order key
$test_order_key = $order->get_order_key();
if ( $order->has_status('on-hold') || $order->has_status('mockup-requested') || $order->has_status('mockup-sent')|| $order->has_status('mockup-approved')) {
echo 'helllo world';
add_filter( 'the_title', 'woo_title_order_received', 10, 2 );
function woo_title_order_received( $title, $id ) {
if ( function_exists( 'is_order_received_page' ) &&
is_order_received_page() && get_the_ID() === $id ) {
$title = "Mockup request received";
}
return $title;
}
}
}
but I have tried multiple ways to combine the two and without any success.
You can use the following to change "Order received" page title based on order statuses:
add_action( 'the_title', 'change_order_received_page_title_based_on_order_status' );
function change_order_received_page_title_based_on_order_status( $title ){
if ( is_wc_endpoint_url('order-received') && $title === 'Order received' ) {
global $wp;
$targeted_statuses = array('on-hold', 'mockup-requested', 'mockup-sent', 'mockup-approved' );
// Get an instance of the `WC_Order` Object
$order = wc_get_order( absint($wp->query_vars['order-received']) );
if ( is_a( $order, 'WC_Order' ) && in_array( $order->get_status(), $targeted_statuses ) ) {
return __("Mockup request received", "woocommerce");
}
}
return $title;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Related
I have a php function that creates a new session (WC()->session->set).
I want to make a link on site's header that calls a function to remove that session ( WC()->session->set( 'the_session', null );
how it should be done? couldn't find a way :(
tried to use $_get on functions, which didn't work
EDIT:
here is the code Im using, it add's the option to edit orders that have been made already:
/**
* #snippet Edit Order Functionality # WooCommerce My Account Page
* #how-to Get CustomizeWoo.com FREE
* #sourcecode https://businessbloomer.com/?p=91893
* #author Rodolfo Melogli
* #compatible WooCommerce 4.1
* #donate $9 https://businessbloomer.com/bloomer-armada/
*/
// ----------------
// 1. Allow Order Again for Processing Status
add_filter( 'woocommerce_valid_order_statuses_for_order_again', 'bbloomer_order_again_statuses' );
function bbloomer_order_again_statuses( $statuses ) {
$statuses[] = 'processing';
return $statuses;
}
// ----------------
// 2. Add Order Actions # My Account
add_filter( 'woocommerce_my_account_my_orders_actions', 'bbloomer_add_edit_order_my_account_orders_actions', 50, 2 );
function bbloomer_add_edit_order_my_account_orders_actions( $actions, $order ) {
if ( $order->has_status( 'processing' ) ) {
$actions['edit-order'] = array(
'url' => wp_nonce_url( add_query_arg( array( 'order_again' => $order->get_id(), 'edit_order' => $order->get_id() ) ), 'woocommerce-order_again' ),
'name' => __( 'שנה בחירה', 'woocommerce' )
);
}
return $actions;
}
// ----------------
// 3. Detect Edit Order Action and Store in Session
add_action( 'woocommerce_cart_loaded_from_session', 'bbloomer_detect_edit_order' );
function bbloomer_detect_edit_order( $cart ) {
if ( isset( $_GET['edit_order'], $_GET['_wpnonce'] ) && is_user_logged_in() && wp_verify_nonce( wp_unslash( $_GET['_wpnonce'] ), 'woocommerce-order_again' ) ) WC()->session->set( 'edit_order', absint( $_GET['edit_order'] ) );
}
// ----------------
// 4. Display Cart Notice re: Edited Order
add_action( 'woocommerce_before_cart', 'bbloomer_show_me_session' );
function bbloomer_show_me_session() {
if ( ! is_cart() ) return;
$edited = WC()->session->get('edit_order');
if ( ! empty( $edited ) ) {
$order = new WC_Order( $edited );
$credit = $order->get_total();
wc_print_notice( 'A credit of ' . wc_price($credit) . ' has been applied to this new order. Feel free to add products to it or change other details such as delivery date.', 'notice' );
}
}
// ----------------
// 5. Calculate New Total if Edited Order
add_action( 'woocommerce_cart_calculate_fees', 'bbloomer_use_edit_order_total', 20, 1 );
function bbloomer_use_edit_order_total( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
$edited = WC()->session->get('edit_order');
if ( ! empty( $edited ) ) {
$order = new WC_Order( $edited );
$credit = -1 * $order->get_total();
$cart->add_fee( 'Credit', $credit );
}
}
// ----------------
// 6. Save Order Action if New Order is Placed
add_action( 'woocommerce_checkout_update_order_meta', 'bbloomer_save_edit_order' );
function bbloomer_save_edit_order( $order_id ) {
$edited = WC()->session->get( 'edit_order' );
if ( ! empty( $edited ) ) {
// update this new order
update_post_meta( $order_id, '_edit_order', $edited );
$neworder = new WC_Order( $order_id );
$oldorder_edit = get_edit_post_link( $edited );
$neworder->add_order_note( 'Order placed after editing. Old order number: ' . $edited . '' );
// cancel previous order
$oldorder = new WC_Order( $edited );
$neworder_edit = get_edit_post_link( $order_id );
$oldorder->update_status( 'cancelled', 'Order cancelled after editing. New order number: ' . $order_id . ' -' );
WC()->session->set( 'edit_order', null );
}
}
I want to make a button on my website header, that removes the session after the user clicked "edit order", if he decided to cancel the editing and stay with his original order, the line that does that is
WC()->session->set( 'edit_order', null );
and I want it to be a link
Found the right way:
add_action('afterheader','leave_edit_order');
function after_header_block_yhm()
{
do_action( 'afterheader');
}
add_shortcode('under_header_location','after_header_block_yhm');
function leave_edit_order(){
$edited = WC()->session->get('edit_order');
if(!empty($edited) && isset($_GET['cancel_edit_order'])){
WC()->session->set( 'edit_order', null );
wc_print_notice( 'You left "edit order" session, enjoy your stay.' );
}
add_action('afterheader','leave_edit_order');
Made a new action called 'afterheader" and a new shortcode called 'under_header_location',
then used elementor to put the shortcode in the place I wanted, and then called the function in that new action I made
on the function Im checking that the user has ?cancel_edit_order on his url and then calling the function
I have the following code in my functions.php file:
add_filter( 'woocommerce_order_number', 'change_woocommerce_order_number' );
function change_woocommerce_order_number( $order_id ) {
$order = wc_get_order( $order_id );
//$order->get_total();
$method_of_payment = $order->get_payment_method();
if ( $method_of_payment == 'cheque' ) {
$prefix = 'CHE';
$suffix = '';
$new_order_id = $prefix . $order_id . $suffix;
return $new_order_id;
} else {
return $order_id;
}
}
The code works but I want it to permanently save the new order number. It should permanently make CHEXXXX (ex. CHE5783) the order number in the database if the user checked out using check payments. Right now this code only makes it temporary. It does not need to update previous order numbers, only new orders.
As the method WC_Order set_order_number() doesn't exist, we will add a custom field (custom meta data) when an order is placed (on order creation). Then we will get that order custom meta data in woocommerce_order_number filter hook.
The code:
add_action( 'woocommerce_checkout_update_order_meta', 'save_the_order_number', 10, 2 );
function save_the_order_number( $order_id, $data ) {
$order = wc_get_order( $order_id ); // The order Object
if ( 'cheque' === $order->get_payment_method() ) {
$prefix = 'CHE';
$suffix = '';
} else {
$prefix = '';
$suffix = '';
}
update_post_meta( $order_id, '_order_number', $prefix . $order_id . $suffix );
}
add_filter( 'woocommerce_order_number', 'set_order_number', 10, 2 );
function set_order_number( $order_id, $order ) {
// Get the order number (custom meta data)
$order_number = $order->get_meta('_order_number');
// If the order number doesn't exist (we keep that for old orders, or manual orders)
if ( empty($order_number) ) {
if ( 'cheque' === $order->get_payment_method() ) {
$prefix = 'CHE';
$suffix = '';
$order_number = $prefix . $order_id . $suffix;
} else {
$order_number = $order_id;
}
}
return $order_number;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and work.
Now if you want to be able to edit the order number on admin order pages, use additionally the following code:
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_admin_order_order_number_custom_field' );
function display_admin_order_order_number_custom_field( $order ){
echo '<div class="edit_order_number"><p class="form-field _order_number_field" style="width:100%;">
<label for="_order_number">'. __("Order number", "woocommerce").':</label>
<input type="text" id="_order_number" name="_order_number" value="'. $order->get_order_number() .'">
</p></div>';
}
add_action( 'save_post_shop_order', 'save_admin_order_order_number_custom_field' );
function save_admin_order_order_number_custom_field( $post_id ) {
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
// Check the user's permissions.
if ( ! current_user_can( 'edit_shop_order', $post_id ) ) {
return;
}
// Make sure that 'shipping_date' is set.
if ( isset( $_POST['_order_number'] ) ) {
// Update custom field value
update_post_meta( $post_id, '_order_number', sanitize_text_field( $_POST['_order_number'] ) );
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and work.
I want to redirect to a custom wordpress page if a customers woocommerce order fails.
I have found and implemented the following code which redirects to a new page upon payment success.
Is it possible to add to this code, so a failed order is sent to another specific url ?
add_action( 'woocommerce_thankyou', 'bbloomer_redirectcustom');
function bbloomer_redirectcustom( $order_id ){
$order = wc_get_order( $order_id );
$url = 'https://yoursite.com/custom-url';
if ( ! $order->has_status( 'failed' ) ) {
wp_safe_redirect( $url );
exit;
}
}
Based on the code you have, you can use $order->has_status( 'failed' )
So you get:
function action_woocommerce_thankyou( $order_id ) {
// Get $order object
$order = wc_get_order( $order_id );
// Is a WC_Order
if ( is_a( $order, 'WC_Order' ) ) {
// Settings
$url1 = 'https://yoursite.com/custom-url-1';
$url2 = 'https://yoursite.com/custom-url-2';
// Compare
if ( ! $order->has_status( 'failed' ) ) {
wp_safe_redirect( $url1 );
exit;
} else {
wp_safe_redirect( $url2 );
exit;
}
}
}
add_action( 'woocommerce_thankyou', 'action_woocommerce_thankyou', 10, 1 );
Code goes in functions.php file of the active child theme (or active theme). Tested and works in Wordpress 5.8.1 & WooCommerce 5.8.0
I need to make it so when people press place order on our webshop, they will get redirectet to My Account, but only if the categories is XXX , XXX , XXX
But i can't seem to get it working unfortunally
I have tried using && is_product_category('Category x','Category x','Category x')
// REDIRECT AFTER PLACE ORDER BUTTON!
add_action( 'woocommerce_thankyou', 'KSVS_redirect_custom');
function KSVS_redirect_custom( $order_id ){
$order = new WC_Order( $order_id );
$url = 'https://kanselvvilselv.dk/min-konto/';
if ( $order->status != 'failed' ) {
wp_redirect($url);
exit;
}
}
It is working without putting in && is_product_category('Category x','Category x','Category x'), But then it is working on categories where it should not work.
The following code using dedicated template_redirect hook and WordPress has_term() conditional function (to be used with product categories), will redirect customers after checkout to my account section, when their order contain items from defined product categories:
add_action( 'template_redirect', 'order_received_redirection_to_my_account' );
function order_received_redirection_to_my_account() {
// Only on "Order received" page
if( is_wc_endpoint_url('order-received') ) {
global $wp;
// HERE below define your product categories in the array
$categories = array('Tshirts', 'Hoodies', 'Glasses');
$order = wc_get_order( absint($wp->query_vars['order-received']) ); // Get the Order Object
$category_found = false;
// Loop theough order items
foreach( $order->get_items() as $item ){
if( has_term( $categories, 'product_cat', $item->get_product_id() ) ) {
$category_found = true;
break;
}
}
if( $category_found ) {
// My account redirection url
$my_account_redirect_url = get_permalink( get_option('woocommerce_myaccount_page_id') );
wp_redirect( $my_account_redirect_url );
exit(); // Always exit
}
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Note: i'm not familiar with woocommerce at all, please take my answer with ease.
Seems like function is_product_category have different purpouse, by quick overview I came with this, give it a try:
$redirectWhenCategoryIs = ['cat x', 'cat y', 'cat z'];
$categories = [];
foreach($order->get_items() as $item) {
foreach(get_the_terms($item['product_id'], 'product_cat') as $term){
$categories[] = $term->slug;
}
}
if(count(array_intersect($redirectWhenCategoryIs, $categories))){
wp_redirect($url);
}
Updated, this should loop through all ordered products and if it matches 1 product with a category then it will redirect to your URL:
add_action( 'woocommerce_thankyou', 'KSVS_redirectcustom');
function KSVS_redirectcustom( $order_id ){
$order = wc_get_order( $order_id );
$url = get_permalink( get_option('woocommerce_myaccount_page_id') );
if ( $order->status != 'failed' ) {
$product_cats = array('product-cat1', 'product-cat', 'product-cat3');
foreach ($order->get_items() as $item) {
if ( has_term( $product_cats, 'product_cat', $product->id) ) {
$cat_check = true;
break;
}
}
if ( $cat_check ) {
wp_redirect($url);
exit;
}
}
}
How could I customise the order thank you page based on the order's shipping method? So for example if a customer used 'Delivery on request' option, the thank you page would display a different title.
add_filter( 'the_title', 'woo_personalize_order_received_title', 10, 2 );
function woo_personalize_order_received_title( $title, $id ) {
if ( is_order_received_page() && get_the_ID() === $id ) {
global $wp;
// Get the order. Line 9 to 17 are present in order_received() in includes/shortcodes/class-wc-shortcode-checkout.php file
$order_id = apply_filters( 'woocommerce_thankyou_order_id', absint( $wp->query_vars['order-received'] ) );
$order_key = apply_filters( 'woocommerce_thankyou_order_key', empty( $_GET['key'] ) ? '' : wc_clean( $_GET['key'] ) );
if ( $order_id > 0 ) {
$order = wc_get_order( $order_id );
if ( $order->get_order_key() != $order_key ) {
$order = false;
}
}
if ( isset ( $order ) ) {
$chosen_titles = array();
$available_methods = $wp->shipping->get_packages();
$chosen_rates = ( isset( $wp->session ) ) ? $wp->session->get( 'chosen_shipping_methods' ) : array();
foreach ($available_methods as $method)
foreach ($chosen_rates as $chosen) {
if( isset( $method['rates'][$chosen] ) ) $chosen_titles[] = $method['rates'][ $chosen ]->label;
}
if( in_array( 'Delivery price on request', $chosen_titles ) ) {
//$title = sprintf( "You are awesome, %s!", esc_html( $order->billing_first_name ) ); // use this for WooCommerce versions older then v2.7
$title = sprintf( "You are awesome, %s!", esc_html( $order->get_billing_first_name() ) );
}
}
}
return $title;
}
is_order_received_page() doesn't exist. Instead use is_wc_endpoint_url( 'order-received' )…
Also $wp->session or $wp->shipping will not work. Instead you can find the chosen shipping method data in the order item "shipping".
Try this instead:
add_filter( 'the_title', 'customizing_order_received_title', 10, 2 );
function customizing_order_received_title( $title, $post_id ) {
if ( is_wc_endpoint_url( 'order-received' ) && get_the_ID() === $post_id ) {
global $wp;
$order_id = absint( $wp->query_vars['order-received'] );
$order_key = isset( $_GET['key'] ) ? wc_clean( $_GET['key'] ) : '';
if ( empty($order_id) || $order_id == 0 )
return $title; // Exit
$order = wc_get_order( $order_id );
if ( $order->get_order_key() != $order_key )
return $title; // Exit
$method_title_names = array();
// Loop through Order shipping items data and get the method title
foreach ($order->get_items('shipping') as $shipping_method )
$method_title_names[] = $shipping_method->get_name();
if( in_array( 'Delivery price on request', $method_title_names ) ) {
$title = sprintf( "You are awesome, %s!", esc_html( $order->get_billing_first_name() ) );
}
}
return $title;
}
Code goes on function.php file of your active child theme (or active theme). Tested and works.
Similar: Adding custom message on Thank You page by shipping method in Woocommerce