WooCommerce trigger all orders update - php

I want to trigger action save_post_shop_order by url, because I have custom function that will create product meta there on checking.
I tried something like:
add_action('wp_head', 'update_orders_by_url');
function update_orders_by_url() {
if( isset( $_GET['update_woo_orders'] ) ) {
$query = new WC_Order_Query( array(
'limit' => -1
));
$orders = $query->get_orders();
foreach($orders as $order){
$arra2[] = $order;
// Save
$order->save();
}
}
//echo count($arra2);
}
But seems not working in my case.
How I can trigger update all orders and run action save_post_shop_order for all orders?
Thanks

You can do it this way, put your code in functions.php or a plugin
add_filter( 'handle_bulk_actions-edit-shop_order', 'save_post_shop_order', 10, 3 );
/**
* #param $redirect_to
* #param $action
* #param $post_ids
* #return mixed|string
*/
function save_post_shop_order( $redirect_to, $action, $post_ids ) {
// do your job
return $redirect_to = add_query_arg( array(
'bulk_action_name' => $action,
'processed_count' => count( $processed_ids ),
'processed_ids' => implode( ',', $processed_ids ),
), $redirect_to );
}
add_action( 'admin_notices', 'save_post_shop_order_admin_notice' );
/**
* The results notice from bulk action on orders
*/
function save_post_shop_order_admin_notice() {
$count = intval( $_REQUEST['processed_count'] );
printf( '<div id="message" class="updated fade"><p>' .
_n( "",
"",
$count,
''
) . '</p></div>', $count );
}

To update orders information through the URL, you can try the following steps.
Create a file in your root directory
On the top of the file, add this piece of code.
require(dirname(__FILE__) . '/wp-load.php');
Get all orders
$orders = wc_get_orders( array('numberposts' => -1) );
// Loop through each WC_Order object
foreach( $orders as $order ){
echo $order->get_id() . '<br>'; // The order ID
echo $order->get_status() . '<br>'; // The order status
.......
// do your stuff
}
Now, you will be able to update orders information through URL.
Hit your url/pagename, for example, http://example.com/test.php

Related

WOOCOMMERCE call function from URL

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

Woocommerce Booking Add custom order item meta data

Looking for some help,
The aim is to capture several bits of data when a customer checks-out and for these to be stored as custom order item meta data.
Im looking to capture
Start-date
Start time
End date
End time
For each order, currently using WooCommerce booking and this data goes straight to the reservation area and doesn't appear as custom order item meta data.
Ive found a list of the hooks and filters whilst trying to create code myself, however I think im missing some bits along the way:
https://docs.woocommerce.com/document/bookings-action-and-filter-reference/
https://docs.woocommerce.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/
https://wordpress.stackexchange.com/questions/215219/how-to-display-custom-field-in-woocommerce-orders-in-admin-panel
Ive tried to create this code to add these items to the custom order item meta data but without much success.
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $fields['woocommerce_bookings_after_booking_base_cost'] ) ) {
update_post_meta( $order_id, 'woocommerce_bookings_after_booking_base_cost', sanitize_text_field( $_POST['woocommerce_bookings_after_booking_base_cost'] ) );
}
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('woocommerce_bookings_after_booking_base_cost').':</strong> <br/>' . get_post_meta( $order->get_id(), 'woocommerce_bookings_after_booking_base_cost', true ) . '</p>';
}
Im hoping someone has had this issue before and can share their knowledge or someone could point me in the right direction or help me with the coding, happy to admit I'm not the very best at coding but if someone could help break it down to me a little of where and what Im doing wrong, maybe what I'm doing correct as well, so I can understand how to improve.
Any help?
I also found this code, but it doesn't set the custom order meta data,
WOE_Bookings{
function __construct() {
add_filter('woe_get_order_product_fields',array($this,'add_product_fields') );
add_filter('woe_get_order_product_item',array($this,'fetch_booking') );
//set global filters
add_filter('woe_get_order_product_value_booking_status', array($this,'get_booking_field_status'), 10, 5 );
add_filter('woe_get_order_product_value_booking_start_date', array($this,'get_booking_field_start_date'), 10, 5 );
add_filter('woe_get_order_product_value_booking_start_time', array($this,'get_booking_field_start_time'), 10, 5 );
add_filter('woe_get_order_product_value_booking_end_date', array($this,'get_booking_field_end_date'), 10, 5 );
add_filter('woe_get_order_product_value_booking_end_time', array($this,'get_booking_field_end_time'), 10, 5 );
add_filter('woe_get_order_product_value_booking_resource', array($this,'get_booking_field_resource'), 10, 5 );
add_filter('woe_get_order_product_value_booking_persons_total', array($this,'get_booking_field_persons_total'), 10, 5 );
// add function for person types
if( class_exists("WC_Product_Booking_Data_Store_CPT") AND method_exists("WC_Product_Booking_Data_Store_CPT", "get_person_types_ids") ) {
$person_types_ids = WC_Product_Booking_Data_Store_CPT::get_person_types_ids();
foreach($person_types_ids as $type_id) {
add_filter('woe_get_order_product_value_booking_person_type_'.$type_id, function($value,$order, $item, $product, $item_meta) use ($type_id){
if (!$this->booking)
return $value;
$counters = $this->booking->get_person_counts();
return isset($counters[$type_id]) ? $counters[$type_id] : 0;
}, 10, 5 );
}
}
}
function add_product_fields($fields) {
$fields['booking_status'] = array('label'=>'Booking Status','colname'=>'Booking Status','checked'=>1);
$fields['booking_start_date'] = array('label'=>'Booking Start Date','colname'=>'Booking Start Date','checked'=>1);
$fields['booking_start_time'] = array('label'=>'Booking Start Time','colname'=>'Booking Start Time','checked'=>1);
$fields['booking_end_date'] = array('label'=>'Booking End Date','colname'=>'Booking End Date','checked'=>1);
$fields['booking_end_time'] = array('label'=>'Booking End Time','colname'=>'Booking End Time','checked'=>1);
$fields['booking_resource'] = array('label'=>'Booking Resource','colname'=>'Booking Resource','checked'=>1);
$fields['booking_persons_total'] = array('label'=>'Booking # of Persons','colname'=>'Booking Persons Total','checked'=>1,'segment'=>'cart');
// add person types as columns
if( class_exists("WC_Product_Booking_Data_Store_CPT") AND method_exists("WC_Product_Booking_Data_Store_CPT", "get_person_types_ids") ) {
$person_types_ids = WC_Product_Booking_Data_Store_CPT::get_person_types_ids();
foreach($person_types_ids as $type_id) {
$post = get_post($type_id);
if( $post )
$fields['booking_person_type_'.$type_id] = array('label'=>'Booking Persons - ' .$post->post_title,'colname'=>'Booking Persons - ' .$post->post_title,'checked'=>1);
}
}
return $fields;
}
// booking for item
function fetch_booking($item) {
global $wpdb;
$this->booking = false;
$booking_id = $wpdb->get_var( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key= '_booking_order_item_id' AND meta_value=" . intval( $item->get_id() ) );
if( $booking_id ) {
$this->booking = new WC_Booking($booking_id);
}
return $item;
}
function get_booking_field_status($value,$order, $item, $product, $item_meta) {
return $this->booking ? $this->booking->get_status() : $value;
}
function get_booking_field_start_date($value,$order, $item, $product, $item_meta) {
return $this->booking ? date_i18n( wc_date_format(), $this->booking->start) : $value;
}
function get_booking_field_start_time($value,$order, $item, $product, $item_meta) {
return $this->booking ? date_i18n( wc_time_format(), $this->booking->start) : $value;
}
function get_booking_field_end_date($value,$order, $item, $product, $item_meta) {
return $this->booking ? date_i18n( wc_date_format(), $this->booking->end) : $value;
}
function get_booking_field_end_time($value,$order, $item, $product, $item_meta) {
return $this->booking ? date_i18n( wc_time_format(), $this->booking->end) : $value;
}
function get_booking_field_resource($value,$order, $item, $product, $item_meta) {
if (!$this->booking)
return $value;
$resource = $this->booking->get_resource();
return $resource ? $resource->get_name() : $value;
}
function get_booking_field_persons_total($value,$order, $item, $product,$item_meta) {
return $this->booking ? $this->booking->get_persons_total() : $value;
}
}
new WOE_Bookings();
add_action( 'woocommerce_add_order_item_meta', 'add_order_item_meta' , 10, 2);
function add_order_item_meta ( $item_id, $values ) {
if ( isset( $values [ 'booking_start_date' ] ) ) {
$custom_data = $values [ 'booking_start_date' ];
wc_add_order_item_meta( $item_id, ‘date',
$custom_data['booking_start_date'] );
}
}
You don't need to add any custom meta data to the order, as you can retrieve it easily (as you are expecting).
You will see in the following code example that displays the start date, the start time, the End date and the End time in admin single orders below shipping address:
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_some_booking_data_to_admin_orders', 10, 1 );
function display_some_booking_data_to_admin_orders( $order ){
// Retreive the booking Ids that belong to an order
$bookings_ids = get_posts( array(
'posts_per_page' => -1,
'post_type' => 'wc_booking', // booking post type
'post_parent' => $order->get_id(),
'post_status' => 'all',
'fields' => 'ids',
) );
if( ! empty($bookings_ids) ) {
echo '<div class="booking-items">';
// Loop through Bookings for the current order
foreach ( $bookings_ids as $booking_id ) {
// Get an instance of the WC_Booking Object
$booking = new WC_Booking( $booking_id );
// Get the related instance of the order Item Object
$item = $order->get_item($booking->order_item_id);
$name = $item->get_name(); // Get product name
// Start date and time
$start_datetime = $booking->get_start_date();
$start_dt_array = explode(', ', $start_datetime);
$start_date = reset($start_dt_array); // Start date
$start_time = end($start_dt_array); // Start time
// End date and time
$end_datetime = $booking->get_end_date();
$end_dt_array = explode(', ', $end_datetime);
$end_date = reset($end_dt_array); // End date
$end_time = end($end_dt_array); // End time
echo '<table style="border:solid 1px #eee; margin-bottom:12px;">
<thead style="background-color: #eee;">
<tr><td><strong>' . __("Booking") . ':</strong></td><td> ' . $name . ' <em><small>(' . $booking_id . ')</small></em></td></tr>
</thead>
<tbody>
<tr><td><strong>' . __("Start date") . ':</strong></td><td>' . $start_datetime . '</td></tr>
<tr><td><strong>' . __("End date") . ':</strong></td><td>' . $end_datetime . '</td></tr>
</tbody>
</table>';
}
echo '</div>';
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Addition for Exporting order data
Save booking data as custom order meta data (only handle one booking):
add_action( 'woocommerce_checkout_create_order', 'display_some_booking_data_to_admin_orders', 10, 1 );
function display_some_booking_data_to_admin_orders( $order ){
$cart_items = WC()->cart->get_cart(); // Get cart items
$cart_item = reset($cart_item); // First cart item
if( isset($cart_item['booking']) && ! empty($cart_item['booking']) ) {
$booking_id = $cart_item['booking']['_booking_id'];
$order->update_meta_data( '_booking_id', $booking_id ); // Save booking Id
// Get an instance of the WC_Booking Object
$booking = new WC_Booking( $cart_item['booking']['_booking_id'] );
// Start date and time
$start_datetime = $booking->get_start_date();
$start_dt_array = explode(', ', $start_datetime);
$order->update_meta_data( 'booking_start_datetime', $start_datetime ); // Save start date and time
$order->update_meta_data( 'booking_start_date', reset($start_dt_array) ); // Save start date
$order->update_meta_data( 'booking_start_time', end($start_dt_array) ); // Save start time
// End date and time
$end_datetime = $booking->get_end_date();
$end_dt_array = explode(', ', $end_datetime);
$order->update_meta_data( 'booking_end_datetime', $end_datetime ); // Save end date and time
$order->update_meta_data( 'booking_end_date', reset($end_dt_array) ); // Save end date
$order->update_meta_data( 'booking_end_time', end($end_dt_array) ); // Save end time
// Cost and quantiity
$order->update_meta_data( 'booking_cost', $cart_item['booking']['_cost'] ); // Save cost
$order->update_meta_data( 'booking_qty', $cart_item['booking']['_qty'] ); // Save quantity
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
This will allow you to export the booking data with your plugin.
Please, use this solution to filter by start date
https://wordpress.org/support/topic/filter-by-bookings-start-date/#post-12908495
if you still need help - please, submit ticket to https://algolplus.freshdesk.com/
thanks, Alex
(support of Advanced Order Export For WooCommerce)

Get the order item Id in WooCommerce order items

With WooCommerce, I am trying to change the download URLs for order items. Originally I was using the order ID but that only allows one subscription per order. So I need the customer to be able to purchase more than one subscription.
Here is the code I currently have:
if ( !class_exists( 'pl_wcdf_extention' ) ) {
class pl_wcdf_extention {
public function __construct() {
add_filter( 'woocommerce_order_get_downloadable_items', array( $this, 'download_link' ), 10, 2 );
add_filter( 'woocommerce_customer_get_downloadable_products', array( $this, 'download_link' ), 10, 1 );
}
public function download_link( $downloads, $order = null ) {
$download_url_base = 'https://xxxx.com/';
// retrieve Order ID from Download array
$order_id = $downloads [0]['order_id'];
// retrieve Order data
$order = wc_get_order( $order_id );
// retrieve Order Items
$order_item = $order->get_items();
// retrieve first Order Item ID
$order_item_id = $order_item [0][order_item_id];
foreach ( $downloads as $download ) {
$download['download_url'] = $download_url_base . "xxxx-" . $order_item_id . ".svg";
$tag_item = array(
'--native-libs-dir' => '/home/Lib/',
'--type' => 'template0001style1',
'--data'=> $order_item_id,
'--join' => 'horizontal',
'--output-file' => '/home/public_html/xxxx-' . $order_item_id . '.svg'
);
$args = "";
foreach ($tag_item as $k=>$v) {
$args .= " $k " . " $v ";
}
shell_exec("/home/Python-2.7.14/Python-3.6.3/python /home/Lib/generate-code.py $args");
}
return $downloads;
}
}
}
if ( class_exists( 'pl_wcdf_extention' ) ) {
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
global $wpdb;
define( 'PL_WCDFE_DIR_PATH', plugin_dir_path( __FILE__ ) );
define( 'PL_WCDFE_PLUGIN_FILE', __FILE__ );
new pl_wcdf_extention();
}
Everything works except I am not able to get the order item ID.
Any help would be appreciated.
To retrieve order item id from the WC_Order_Item Object, please use the get_id() method.
So in your script, you should replace this section:
// retrieve first Order Item ID
$order_item_id = $order_item [0][order_item_id];
with this:
// retrieve first Order Item ID
$order_item_id = $order_item[0]->get_id();

Passing custom data from cart items to Order meta in Woocommerce 3

I have implemented a custom HTML Form and asking for some data which my customers will pass to place order successfully. Without these details my order has no importance.
For HTML form, I am referencing some custom PHP script which is below and which processes POST data from the Form and creates Cart with these data programmatically. Thanks #LoicTheAztec to help me achieve this.
The script.php file code:
<?php
require_once("../wp-load.php");
$customer_name = $_POST["customer_name"];
$customer_email = $_POST["customer_email"];
$customer_sex = $_POST["customer_sex"];
$customer_age = $_POST["customer_age"];
$product_id = $_POST["product_id"];
$custom_data = array(); // Initializing
if( isset($_POST['customer_name']) && ! empty($_POST['customer_name']) )
$custom_data['custom_data']['name'] = $_POST['customer_name'];
if( isset($_POST['customer_email']) && ! empty($_POST['customer_email']) )
$custom_data['custom_data']['email'] = $_POST['customer_email'];
if( isset($_POST['customer_sex']) && ! empty($_POST['customer_sex']) )
$custom_data['custom_data']['sex'] = $_POST['customer_sex'];
if( isset($_POST['customer_age']) && ! empty($_POST['customer_age']) )
$custom_data['custom_data']['age'] = $_POST['customer_age'];
global $woocommerce;
if (WC()->cart->add_to_cart( $product_id, '1', '0', array(), $custom_data )) {
var_dump($product_id);
} else {
var_dump($customer_name);
}
header("Location: ./checkout");
?>
As you see we have programmatically created a cart item using WC_Cart add_to_cart() method. So, all custom data is being saved to Cart as custom cart item data.
And now, we have also placed a code block into functions.php to print these data on Checkout page.
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
//var_dump($checkout);
global $woocommerce;
echo '<div id="my_custom_checkout_field"><h2>' . __('Child Info') . '</h2>';
foreach ( $woocommerce->cart->get_cart() as $cart_item ) {
if( isset($cart_item['custom_data']) ) {
$custom_data = $cart_item['custom_data'];
echo("<div>Name: <strong>" . $custom_data['name'] . "</strong></div>");
echo("<div>Email: <strong>" . $custom_data['email'] . "</strong></div>");
echo("<div>Gender: <strong>" . $custom_data['sex'] . "</strong></div>");
echo("<div>Age: <strong>" . $custom_data['age'] . "</strong></div>");
}
}
echo '</div>';
}
Now, I am trying to add these data printed on Checkout page to the Order page as well. As my order can't be completed without these data, user need to fill up these data and when he creates order, these data needs to be passed to the Order Summary page as well. And admin also needs to be able to see these data so he can process the order.
I hope this description clears everything and thanks again #LoicTheAztec to make me able to do this. Thank you very much.
Update 2 - Two steps
1) Saving data:
We will save this custom customer data as "Hidden" order "item" meta data and then as order meta data too as this is related to subscriptions with a unique order item:
// Utility function: array of custom customer key/label pairs
function custom_data_keys_labels(){
return array(
'name' => __('Customer name'), 'email' => __('Customer email'),
'sex' => __('Customer gender'), 'age' => __('Customer age'),
);
}
// Add/save custom field value as custom HIDDEN order item meta data
add_action( 'woocommerce_checkout_create_order_line_item', 'custom_field_update_order_item_meta', 20, 4 );
function custom_field_update_order_item_meta( $item, $cart_item_key, $values, $order ) {
if ( ! isset( $values['custom_data'] ) )
return;
$custom_data = $values['custom_data'];
$meta_data = array();
$labels_keys = custom_data_keys_labels();
foreach( $labels_keys as $key => $label ){
if ( isset( $custom_data[$key] ) )
$meta_data[$key] = $custom_data[$key];
}
if ( sizeof( $meta_data ) > 0 )
$item->update_meta_data( __('_customer_data'), $meta_data );
return $cart_item_data;
}
// Add/save custom fields values as custom order meta data
add_action( 'woocommerce_checkout_create_order', 'my_custom_checkout_field_update_order_meta', 20, 2 );
function my_custom_checkout_field_update_order_meta( $order, $data ) {
$order_items = $order->get_items(); // Order itesm
$item = reset($order_items); // Keep only the first order item
$item_data = $item->get_meta( '_customer_data' ); // Get custom customer data
if( is_array($item_data) && sizeof($item_data) > 0 ){
foreach( $item_data as $key => $value ) {
if ( isset( $item_data[$key] ) )
$order->update_meta_data( '_customer_' . $key, $value );
}
// Mark as data saved
$order->update_meta_data( '_customer_data_set', true );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
2) Displaying saved custom data:
The code below also use our utility function custom_data_keys_labels()…
// Order pages (frontend and admin) display
add_filter( 'woocommerce_order_details_after_order_table' , 'display_admin_order_meta_cutom_data', 20, 1 ); // Front
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_admin_order_meta_cutom_data', 20, 1 ); // Admin
function display_admin_order_meta_cutom_data( $order ){
$labels_keys = custom_data_keys_labels();
if( $order->get_meta( '_customer_data_set' ) ){
if( is_admin() ){ // Admin
echo '<p>';
foreach( $labels_keys as $key => $label ){
if ( $order->get_meta( '_customer_' . $key ) )
echo '<strong>' . $label . ':</strong> ' . $order->get_meta( '_customer_' . $key ) . '<br>';
}
echo '</p>';
}
else { // Front end: order view and Order received (thankyou)
echo '<table class="woocommerce-table"><tbody>';
foreach( $labels_keys as $key => $label ){
if ( $order->get_meta( '_customer_' . $key ) )
echo '<tr><th>' . $label . ':</th><td>' . $order->get_meta( '_customer_' . $key ) . '</td></tr>';
}
echo '</tbody></table>';
}
}
}
// Email notifications display
add_filter( 'woocommerce_email_order_meta_fields' , 'display_email_cutom_data', 20, 3 );
function display_email_cutom_data ( $fields, $sent_to_admin, $order ) {
$labels_keys = custom_data_keys_labels();
if( $order->get_meta( '_customer_data_set' ) ){
foreach( $labels_keys as $key => $label ){
$fields['customer_' . $key] = array(
'label' => $label,
'value' => $order->get_meta( '_customer_' . $key ),
);
}
}
return $fields;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Woocommerce: product id in the order received url

I would like to change the order received (thanks page) url for a new one, which includes the ordered product's ID.
Here is the code in the class-wc-order.php
/**
* Generates a URL for the thanks page (order received).
*
* #return string
*/
public function get_checkout_order_received_url() {
$order_received_url = wc_get_endpoint_url( 'order-received', $this->get_id(), wc_get_page_permalink( 'checkout' ));
if ( 'yes' === get_option( 'woocommerce_force_ssl_checkout' ) || is_ssl() ) {
$order_received_url = str_replace( 'http:', 'https:', $order_received_url );
}
$order_received_url = add_query_arg( 'key', $this->get_order_key(), $order_received_url );
return apply_filters( 'woocommerce_get_checkout_order_received_url', $order_received_url, $product, $this, $product->id );
}
Any idea?
Thanks!
This answer on wordpress.stackexchange.com would solve the issue
As a brief, just define the following hook:
add_filter('woocommerce_get_checkout_order_received_url','override_return_url',10,2);
function override_return_url($return_url,$order){
//create empty array to store url parameters in
$sku_list = array();
// retrive products in order
foreach($order->get_items() as $key => $item)
{
$product = wc_get_product($item['product_id']);
//get sku of each product and insert it in array
$sku_list['product_'.$item['product_id'] . 'sku'] = $product->get_sku();
}
//build query strings out of the SKU array
$url_extension = http_build_query($sku_list);
//append our strings to original url
$modified_url = $return_url.'&'.$url_extension;
return $modified_url;
}
Then, you can set the analytics goal to point to the destination below as a regular expression
\/checkout\/order-received\/\d+\/\?key=\w+&product_ID_HERE_sku=SKU_HERE
We can make it simpler by including only product ids:
add_filter('woocommerce_get_checkout_order_received_url','override_return_url',0,2);
function override_return_url($return_url,$order){
$ids = array();
foreach($order->get_items() as $key => $item)
{
$ids[] = $item['product_id'];
}
return add_query_arg('product_ids', join(',', $ids) , $return_url);
}
In this case, the regex would be:
\/checkout\/order-received\/\d+\/\?key=\w+&product_ids=ID1,ID2,ID3
Or for a single product id:
\/checkout\/order-received\/\d+\/\?key=\w+&product_ids=[\w,]*ID[\w,]*

Categories